Scrapy bot 和 shell return 具有相同 xpath 查询的不同结果。为什么?
Scrapy bot and shell return different results with same xpath query. Why?
当我在 scrapy 机器人和 scrapy shell 中执行相同的 xpath 查询时,我得到了不同的结果。
注意:我只是想学习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()
我想要的只是州 public 图书馆页面的链接(参见网页)。
这是 shell 显示的内容(这正是我想要的):
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']}
据我所知,机器人 返回的许多 elements/links 不适合 xpath 选择器。这是怎么回事?有人可以解释我做错了什么吗?
非常感谢!
看看你的parse
函数。这一行 response.xpath('//div/div/div/ul/li/a/@href')
将为您提供所有 link 列表到您想要的州图书馆。现在,您将遍历所有已抓取的 links 并使用此行 yield scrapy.Request(url, callback=self.parse_dir_contents)
跟随 links。然后你的机器人正在回调函数 parse_dir_contents
。在此函数中,您的机器人正在选择 xpath //ul/li
中存在的所有元素。因此,您在输出中看到的 link 实际上出现在随后的 link 页面中,而不是 start_url's
页面中。这就是 shell 输出和 spider 输出之间存在差异的原因。 shell 输出仅显示您传递给它的 url 中的 link。您可以通过访问 url http://www.lib-web.org/united-states/public-libraries/alabama/
来交叉检查您的结果,并检查它是否包含此 url http://www.dirbuzz.com
.
当我在 scrapy 机器人和 scrapy shell 中执行相同的 xpath 查询时,我得到了不同的结果。
注意:我只是想学习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()
我想要的只是州 public 图书馆页面的链接(参见网页)。
这是 shell 显示的内容(这正是我想要的):
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']}
据我所知,机器人 返回的许多 elements/links 不适合 xpath 选择器。这是怎么回事?有人可以解释我做错了什么吗?
非常感谢!
看看你的parse
函数。这一行 response.xpath('//div/div/div/ul/li/a/@href')
将为您提供所有 link 列表到您想要的州图书馆。现在,您将遍历所有已抓取的 links 并使用此行 yield scrapy.Request(url, callback=self.parse_dir_contents)
跟随 links。然后你的机器人正在回调函数 parse_dir_contents
。在此函数中,您的机器人正在选择 xpath //ul/li
中存在的所有元素。因此,您在输出中看到的 link 实际上出现在随后的 link 页面中,而不是 start_url's
页面中。这就是 shell 输出和 spider 输出之间存在差异的原因。 shell 输出仅显示您传递给它的 url 中的 link。您可以通过访问 url http://www.lib-web.org/united-states/public-libraries/alabama/
来交叉检查您的结果,并检查它是否包含此 url http://www.dirbuzz.com
.