Бот Scrapy и оболочка возвращают разные результаты с одним и тем же запросом xpath. Почему?

Когда я выполняю один и тот же запрос xpath в бот-боте и в оболочке scrapy, я получаю разные результаты.

Примечание. Я просто пытаюсь изучить scrapy и поэтому модифицирую часть кода учебника. Пожалуйста, иди со мной медленно.

Запрос:

xpath('//div/div/div/ul/li/a/@href')

Бот:

import scrapy

from tutorial.items import DmozItem

class DmozSpider(scrapy.Spider):
    name = "dmoz"
    allowed_domains = ["lib-web.org"]
    start_urls = [
        "http://www.lib-web.org/united-states/public-libraries"
    ]

    def parse(self, response):
        for href in response.xpath('//div/div/div/ul/li/a/@href'):
            url = response.urljoin(href.extract())
            yield scrapy.Request(url, callback=self.parse_dir_contents)


    def parse_dir_contents(self, response):
        for sel in response.xpath('//ul/li'):
            item = DmozItem()
            item['title'] = sel.xpath('a/text()').extract()
            item['link'] = sel.xpath('a/@href').extract()
            item['desc'] = sel.xpath('p/text()').extract()
            yield item

DmozItem:

import scrapy

class DmozItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()
    desc = scrapy.Field()

Мне нужны только ссылки на страницы государственных публичных библиотек (см. веб-страницу).

Вот что показывает оболочка (это именно то, что я хочу):

Admin$ scrapy shell http://www.lib-web.org/united-states/public-libraries
...snip...
In [1]: response.selector.xpath('//div/div/div/ul/li/a/@href')
Out[1]: 
[<Selector xpath='//div/div/div/ul/li/a/@href' data=u'/united-states/public-libraries/alabama/'>,
 <Selector xpath='//div/div/div/ul/li/a/@href' data=u'/united-states/public-libraries/alaska/'>,
...snip. for brevity...
 <Selector xpath='//div/div/div/ul/li/a/@href' data=u'/united-states/public-libraries/wisconsi'>,
 <Selector xpath='//div/div/div/ul/li/a/@href' data=u'/united-states/public-libraries/wyoming/'>]

Когда паук выполняет тот же запрос, я получаю дополнительные выборки href, которые мне не нужны.

Несколько примеров:

2015-11-10 13:27:52 [scrapy] DEBUG: Scraped from <200 http://www.lib-web.org/united-states/public-libraries/alabama/>
{'desc': [], 'link': [u'http://www.dirbuzz.com'], 'title': [u'DirBuzz.com']}
2015-11-10 13:27:52 [scrapy] DEBUG: Scraped from <200 http://www.lib-web.org/united-states/public-libraries/alabama/>
{'desc': [], 'link': [u'http://www.dirville.com'], 'title': [u'DirVille']}
2015-11-10 13:27:52 [scrapy] DEBUG: Scraped from <200 http://www.lib-web.org/united-states/public-libraries/alabama/>
{'desc': [], 'link': [u'http://www.duddoo.com'], 'title': [u'Duddoo.net']}

Насколько я могу судить, многие элементы/ссылки, возвращаемые ботом, не соответствуют селектору xpath. Как это происходит? Может кто-нибудь объяснить, что я делаю неправильно?

Большое спасибо!


person ryan71    schedule 10.11.2015    source источник


Ответы (1)


Посмотрите на свою функцию parse. Эта строка response.xpath('//div/div/div/ul/li/a/@href') даст вам список всех ссылок на нужные вам библиотеки состояний. Теперь вы перебираете все очищенные ссылки и переходите по ссылкам, используя эту строку yield scrapy.Request(url, callback=self.parse_dir_contents). Затем ваш бот вызывает функцию parse_dir_contents. В этой функции ваш бот выбирает все элементы, присутствующие в xpath //ul/li. Таким образом, ссылка, которую вы видите в качестве вывода, на самом деле присутствует на странице следующей ссылки, а не на странице start_url's. Вот почему есть разница между выводом оболочки и выводом паука. Вывод оболочки показывает только ссылки из URL-адреса, который вы ему передали. Вы можете перепроверить свои результаты, посетив URL-адрес http://www.lib-web.org/united-states/public-libraries/alabama/ и проверить, содержит ли он этот URL-адрес http://www.dirbuzz.com.

person Rahul    schedule 10.11.2015
comment
Да. Вот и все! Я чувствую себя немым сейчас. Нубская ошибка. Огромное спасибо! - person ryan71; 11.11.2015