为什么以下两个代码段会提供不同的输出?它们之间的唯一区别是第一种情况下的h1
标记在第二种情况下被h
标记替换。这是因为h1
标签在html中有一个特殊的“含义”吗?我尝试使用h1
到h6
,并且所有人都将[]
作为输出,而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']
答案 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; p
在h
&#34; ok 。