scrapy xpath选择器在h1-h6标签上的行为

时间:2016-12-09 15:40:12

标签: python html xpath scrapy selector

为什么以下两个代码段会提供不同的输出?它们之间的唯一区别是第一种情况下的h1标记在第二种情况下被h标记替换。这是因为h1标签在html中有一个特殊的“含义”吗?我尝试使用h1h6,并且所有人都将[]作为输出,而h7则开始提供[u'xxx']作为输出。

from scrapy import Selector # scrapy version: 1.2.2

text = '<h1><p>xxx</p></h1>'
print Selector(text=text).xpath('//h1/p/text()').extract()
Output[1]: []

text = '<h><p>xxx</p></h>'
print Selector(text=text).xpath('//h/p/text()').extract()
Output[2]: [u'xxx']

2 个答案:

答案 0 :(得分:3)

根据W3C,在p中包含h#标记无效。您可以看到有关此here

的更多信息

无论如何,为了绕过这个并且只使用任何xml结构,你可以像这样更改type

sel = Selector(text="anyxml", type="xml")

这将尊重任何xml结构。

答案 1 :(得分:1)

简短回答是h1 .. h6不应在格式正确的HTML文档中包含<p>,至少lxml(Scrapy Selectors的权限)在解析HTML时不喜欢。 lxml确实处理了错误的格式,但这种情况有点不同。

您可以查看lxml如何解析和序列化HTML代码段:

>>> from scrapy import Selector
>>> text = '<h1><p>xxx</p></h1>'
>>> s = Selector(text=text)
>>> print(s.extract())
<html><body><h1></h1><p>xxx</p></body></html>

因此,当lxml遇到p中的h1标记时,它会将其置于其后。 p元素不会丢失,但在阅读HTML源代码时,它并不是您所期望的。

与其他代码段相比:

>>> text = '<h><p>xxx</p></h>'
>>> s = Selector(text=text)
>>> print(s.extract())
<html><body><h><p>xxx</p></h></body></html>
>>> 

h元素对lxml没有任何特殊意义,所以&#34; ph&#34; ok