我尝试使用网站http://quotes.toscrape.com/
学习response.xpath和response.cssscrapy shell 'http://quotes.toscrape.com'
for quote in response.css("div.quote"):
title = quote.css("span.text::text").extract()
这将只获得一个值。 但如果我使用xpath:
scrapy shell 'http://quotes.toscrape.com'
for quote in response.css("div.quote"):
title = quote.xpath('//*[@class="text"]/text()').extract()
它将获得整个页面上所有标题的列表。
有些人可以告诉我使用这两种工具有什么不同吗?我更喜欢使用response.xpath的一些元素,比如特定的表内容,很容易通过follow-sibling获得,但是response.css无法获取
答案 0 :(得分:2)
有关XPath和CSS之间差异的一般说明,请参阅Scrapy docs:
Scrapy带有自己的提取数据机制。他们是 称为选择器,因为它们“选择”HTML的某些部分 由XPath或CSS表达式指定的文档。
XPath是一种用于在XML文档中选择节点的语言 也可以与HTML一起使用。 CSS是一种将样式应用于HTML的语言 文档。它定义了选择器以将这些样式与之关联 特定的HTML元素。
XPath提供了比纯CSS选择更多的功能(Wikipedia article提供了一个很好的概述),代价是难以学习。 Scrapy在内部将CSS选择器转换为XPath,因此.css()
函数基本上是.xpath()
的语法糖,你可以使用你感觉更舒服的那个。
关于您的具体示例,我认为问题在于您的XPath查询实际上并不是相对于前一个选择器(引用div),而是对整个文档是绝对的。请参阅Scrapy文档中的"Working with relative XPaths"引用:
请记住,如果您正在嵌套选择器并使用XPath 以/开头,XPath对文档是绝对的,而不是 相对于您从中调用它的选择器。
要获得与CSS选择器相同的结果,您可以使用类似这样的内容,其中XPath查询相对于引用div:
for quote in response.css('div.quote'):
print(quote.xpath('span[@class="text"]/text()').extract())
请注意,XPath也有.
expression来进行相对于当前节点的任何查询,但我不确定Scrapy如何实现这一点(使用'.//*[@class="text"]/text()'
也会给出你想要的结果)。