我想在这个网站上提取数据:http://www.pokepedia.fr/pikachu我正在学习python,以及如何使用scrappy,我的问题是:为什么我不能用xpath检索数据?

当我在浏览器中测试xpath时,xpath看起来很好,它会返回正确的值。(谷歌Chrome)

import re
from scrapy import Spider
from scrapy.selector import Selector
from stack.items import StackItem
class StackSpider(Spider):
name ="stack"
allowed_domains = ["pokepedia.fr"]
start_urls = [
"http://www.pokepedia.fr/Pikachu",
]
def unicodize(seg):
if re.match(r'\\u[0-9a-f]{4}', seg):
return seg.decode('unicode-escape')
return seg.decode('utf-8')
def parse(self, response):
pokemon = Selector(response).xpath('//*[@id="mw-content-text"]/table[2]')
for question in pokemon:
item = StackItem()
item['title'] = question.xpath(
'//*[@id="mw-content-text"]/table[2]/tbody/tr[1]/th[2]/text()').extract()[0]
yield item

我想在页面中提取口袋妖怪的名字,但当我使用:

scrapy crawl stack -o items.json -t json

我的JSON输出:

[

在我的控制台中出现以下错误:

IndexError : list index out of range

我遵循这个图图:https://realphython.com/blog/python/web-scraping-with-scrappy-and-mongodb/

如所提供的答案所述,请小心信任任何Web浏览器dev-console/xpath-viewer,因为它们显示的文档并不总是页面生成的确切HTML。通常它会添加标记,并修复任何损坏的HTML。通常最好直接下载页面的HTML(简单的python脚本可以做到)和Word。刮网是一个很好的学习工具,但要记住这个技巧,它已经咬了我几次了。

试试这个

question.xpath( '//*[@id="mw-content-text"]/table[2]/tr[1]/th[2]/text()').extract()[0]

浏览器添加tbody标记。它们不在原始的HTML中,所以scrapy返回一个空文件。

附言:你可能想考虑使用

scrapy shell URL

然后使用

response.xpath('...YOUR SELECTOR..')

用于调试和测试。

在我的浏览器中可以正常工作,但使用Scrapy时,我的输出是空的。您的答案是/text()而不是.text()时出错

@昆汀,我编辑了我的答案,再检查一遍,它应该可以工作。

shell返回带有xpath表达式的空数组,但感谢您让我发现crapy shell fort测试和调试。

你确定?运行scrapy shell http://www.pokepedia.fr/Pikachu和response.xpath( '//*[@id="mw-content-text"]/table[2]/tr[1]/th[2]/text()').extract()[0]后,输出应为pikachu。

好的,它在shell中工作,但在浏览器中返回一个空数组。您有下载HTML内容吗?

问题是,浏览器对HTML代码的解释不同于Scrapy。因此,您通常会在浏览器中使用xpath选择器,但不使用scrappy和其他方法。原因是浏览器试图根据某些标准修复HTML代码,而Scrapy并不麻烦。因此,如果代码在shell中工作,那么它将与刮刀一起工作。

很好的解释,我理解。例如,我看到浏览器在生成HTML中添加tbody,但是这个代码不存在,因为scrapy是由浏览器生成的。

确切地。当你有选择的时候,试着根据他们的类或ID,即ID来定位项目。在所有的浏览器中,ID都是一样的,特别是当网站更新其内容时,ID最不容易改变。