我在理解如何使用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调用是否应该在新的根目录下工作?
答案 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>
)。