本帖最后由 MyModHeaven 于 2023-2-1 21:05 编辑
这个问题很小,也很简单,但是对我产生了一些困扰。记录一下
在 xpath 中,用 / 表示在子节点中检索,用 // 表示在子孙节点中检索。
在 xpath 路径中,开头用的是 / 或者 //,那么就会把检索的指针放到文档的根节点处(即使此时xpath前面的是某个节点);开头用的是 . 或者 .. ,才会从当前节点或者当前节点的父节点开始找
现在,有一段html,要获得script节点中的文本,这么写却报错:
html = '''
<a href="/html/movie/pc/guochan_405502505600452.html" target="_blank">
<script type="text/javascript">
document.write(d('44CQ6buR5a6i56C06Kej44CR5oqK5Y+w5Y2X5p+Q6aWt5bqX5p+c5Y+w5bCP5aeQ5aeQIO+4j+iwg+aVmeaIkOWQrOivneWltOmatg=='));
</script>
</a>
'''
title = etree.HTML(html).xpath("./script")[0]
只有 etree.HTML(html).xpath("//script")[0] 才可以,为什么呢?因为此时的“当前节点”不是a。
(当然,在完整的程序中这么写很可能不会报错,因为完整的代码中xpath前面的很可能是个经历过 etree.HTML() 洗礼的 <Element html at ××××××××>)
中间差距的产生,是 lxml 自动补全造成的
html = '''
<a href="/html/movie/pc/guochan_405502505600452.html" target="_blank">
<script type="text/javascript">
document.write(d('44CQ6buR5a6i56C06Kej44CR5oqK5Y+w5Y2X5p+Q6aWt5bqX5p+c5Y+w5bCP5aeQ5aeQIO+4j+iwg+aVmeaIkOWQrOivneWltOmatg=='));
</script>
</a>
'''
node = etree.HTML(html)
print(etree.tostring(node))
print(node.xpath('.'))[/mw_shl_code]
两次输出的都是:
b'<html><body><a href="/html/movie/pc/guochan_405502505600452.html" target="_blank">\n <script type="text/javascript">\n document.write(d(\'44CQ6buR5a6i56C06Kej44CR5oqK5Y+w5Y2X5p+Q6aWt5bqX5p+c5Y+w5bCP5aeQ5aeQIO+4j+iwg+aVmeaIkOWQrOivneWltOmatg==\'));\n </script>\n</a>\n</body></html>'
经过 etree.HTML() 的洗礼,它自动补全了!!!
所以“当前节点”不是a!!!
在完整的代码中,xpath路径开头我没有加点,所以尽管xpath前面是节点a,还是报错;把节点a复制出来,用 ./script 还是报错,用 //script 才行。我就疑惑了,明明 script 就是 a 的子节点啊,然后想起了它会自动补全。
唉,基础不牢,地动山摇。野路子就是容易掉坑里
|