python - Scrapy 和 xpath 怪异——自动添加标签、轴和步骤?
问题描述
我无法理解如何将 xpaths 与 scrapy 一起使用的一些细节。例如:
我没有添加的额外 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>
html-body 标签填充来自哪里?
轴和台阶??
sel.xpath('html').extract() # returns [], ok
sel.xpath('body').extract() # returns '<body><a ...' ?????
sel.xpath('a').extract() # returns [], ok?
为什么我可以选择“body”而不使用“/”?我对项目中的“div”元素有类似的行为。
还有以下内容:
sel.xpath('//body').extract() # returns '<body>...', ok
sel.xpath('//body').xpath('/body').extract()
# this returns [].
为什么 xpath 链返回的结果与第一行不同?两种情况下的选择器似乎相同?第二个 xpath 调用不应该在新根上工作吗?
解决方案
Scrapy Selector 使用lxml.html
解析器来解析输入文本,当 lxml 接收到非完整的 html(html 片段)时,它总是将它包装成一个完整的 html 文档树,我相信(例如,Web 浏览器的工作方式相同)。
Xpath 表达式的工作方式与基本文件系统路径表达式非常相似,例如/home/john/Downloads/file.pdf
(absolute path) 或Downloads/file.pdf
(relative path and is same as ./Downloads/file.pdf
)。
简单的 XPath 表达式如body
也一样./body
,表示从当前节点开始定位<body>
元素,该元素应该是当前节点的直接子节点。点表示当前节点,单斜杠表示它下面的一个级别(双破折号表示下面的任何级别)。
默认情况下,您位于相对于 html 树根(<html>
节点)的位置。根节点没有直接的子元素<html>
,所以xpath('html')
什么也没有。根节点确实有一个直接<body>
子节点,因此xpath('body')
产生它。根节点没有直接<a>
子节点,因此不会xpath('a')
产生任何结果(但是您可以通过 检索它xpath('.//a')
)。
这种链接xpath('//body').xpath('/body')
并不像您认为的那样工作。首先,以/
or开始表达式//
(两者都是绝对路径)指示评估器开始相对于文档的根进行查找,而不考虑您当前的位置。所以你的表达方式是:在文档中的任何地方找到 body 元素,然后找到必须位于最顶部的 body 元素(除了顶部只有一个元素,那就是<html>
)。
推荐阅读
- javascript - 在不覆盖属性的情况下结合 javascript 和 concat 值中的 2 个对象
- php - 如何从 PHP 中的数据库和文件夹中删除图像
- amazon-ec2 - Terraform 设置提示:跨 VPC 的 TLS 通信
- pyomo - Pyomo 中多阶段模型的工作示例
- swift - 如果文件不存在,如何在文档文件夹中创建文件?
- spring-boot - CircleCI 中的 Gradle 测试失败-找不到 Lombok 生成代码的符号
- python - 如何读取文本文件以转换为字典?
- javascript - 开玩笑:如何将参数传递给模拟构造函数?
- python - 如何让不和谐机器人输出用户输入的所有内容,而不仅仅是第一个输入?
- r - 在R中的FOR循环内传递带有条件的变量名