Scrapy和xpath怪异-自动添加标签,轴和步骤?

时间:2018-10-06 11:42:43

标签: python xpath scrapy

我在理解如何使用scrapy的xpath的一些细节方面遇到麻烦。例如:

我没有添加的额外HTML正文填充

> git submodule update --init --recursive

填充的html-body标签来自哪里?

轴和步骤?

from scrapy.selector import Selector
t = '<a href="123">qwer</a>'
sel = Selector(text=t)

sel.extract()
# returns: <html><body><a href="123">qwer</a></body></html>

为什么不使用'/'就选择'body'?我在项目中的'div'元素也有类似的行为。

还有以下内容:

sel.xpath('html').extract()  # returns [], ok
sel.xpath('body').extract()  # returns '<body><a ...' ?????
sel.xpath('a').extract()     # returns [], ok?

为什么xpath链返回的内容与第一行相同?两种情况下的选择器似乎相同?第二个xpath调用是否应该在新的根目录下工作?

1 个答案:

答案 0 :(得分:2)

Scrapy Selector使用lxml.html解析器来解析输入文本,并且当lxml收到非完整的html(html片段)时,它总是将其包装为我相信的完整的html文档树(例如,Web浏览器的工作方式相同) )。

Xpath表达式的工作原理与基本文件系统路径表达式类似,例如/home/john/Downloads/file.pdf(绝对路径)或Downloads/file.pdf(相对路径,与./Downloads/file.pdf相同)。

简单的XPath表达式,例如body也与./body相同,这意味着从当前节点开始定位<body>元素,该元素应该是当前节点的直接子代。点表示当前节点,单斜杠表示其下方的单个级别(双破折号表示其下方的任何级别)。

默认情况下,您位于相对于html树根(<html>节点)的位置。根节点没有直接子元素<html>,因此xpath('html')没有任何帮助。根节点确实有一个直接的<body>子节点,因此xpath('body')会产生它。根节点没有直接的<a>子节点,因此xpath('a')不会产生任何子节点(但是您可以通过xpath('.//a')来检索它)。

此链接xpath('//body').xpath('/body')不能按照您认为的方式工作。首先,以///(都是绝对路径)开始表达式会指示评估程序开始相对于文档的根目录查找,而不考虑您当前所在的位置。因此,表达式如下:在文档中的任意位置找到body元素,然后找到必须位于最顶部的body元素(除了顶部只有一个元素,即<html>)。