MyModHeaven 发表于 2023-2-1 20:57

python的lxml库中xpath的一个小问题记录

本帖最后由 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")
```
只有 etree.HTML(html).xpath("//script") 才可以,为什么呢?因为此时的“当前节点”不是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('.'))
```

两次输出的都是:
```
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 的子节点啊,然后想起了它会自动补全。

唉,基础不牢,地动山摇。野路子就是容易掉坑里

duoduo1996 发表于 2023-2-2 10:25

哈哈,我以前也遇到过
页: [1]
查看完整版本: python的lxml库中xpath的一个小问题记录