python - 为什么在使用 lxml(在 python 中)处理 XHTML 文档时 xpath 不起作用?

标签 python xml xhtml xpath lxml

我正在根据以下测试文档进行测试:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
        <title>hi there</title>
    </head>
    <body>
        <img class="foo" src="bar.png"/>
    </body>
</html>

如果我使用 lxml.html 解析文档,我可以使用 xpath 获取 IMG:

>>> root = lxml.html.fromstring(doc)
>>> root.xpath("//img")
[<Element img at 1879e30>]

但是,如果我将文档解析为 XML 并尝试获取 IMG 标记,我会得到一个空结果:

>>> tree = etree.parse(StringIO(doc))
>>> tree.getroot().xpath("//img")
[]

我可以直接导航到元素:

>>> tree.getroot().getchildren()[1].getchildren()[0]
<Element {http://www.w3.org/1999/xhtml}img at f56810>

但这当然不能帮助我处理任意文档。我还希望能够查询 etree 以获取将直接识别此元素的 xpath 表达式,从技术上讲,我可以做到:

>>> tree.getpath(tree.getroot().getchildren()[1].getchildren()[0])
'/*/*[2]/*'
>>> tree.getroot().xpath('/*/*[2]/*')
[<Element {http://www.w3.org/1999/xhtml}img at fa1750>]

但是,xpath 显然对于解析任意文档没有用处。

显然我在这里遗漏了一些关键问题,但我不知道它是什么。我最好的猜测是它与命名空间有关,但唯一定义的命名空间是默认命名空间,我不知道关于命名空间我还需要考虑什么。

那么,我错过了什么?

最佳答案

问题在于命名空间。当解析为 XML 时,img 标签位于 http://www.w3.org/1999/xhtml命名空间,因为这是元素的默认命名空间。您要求没有命名空间中的 img 标签。

试试这个:

>>> tree.getroot().xpath(
...     "//xhtml:img", 
...     namespaces={'xhtml':'http://www.w3.org/1999/xhtml'}
...     )
[<Element {http://www.w3.org/1999/xhtml}img at 11a29e0>]

关于python - 为什么在使用 lxml(在 python 中)处理 XHTML 文档时 xpath 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/297239/

相关文章:

java帮助小程序 Action 监听器

python - fexpect 破坏结构脚本

python - 用于网络抓取的 requests.post 脚本不起作用

具有变量和数据结构的 Python 身份运算符

java - 单击时更改 android 按钮颜色而不更改边框颜色?

xml - SQL Server 查询返回 Xml 和 Html

python - 有条件地从列表中选择下一个元素

java - JAXB validator 未检测到语法错误?

xml - 为什么 &lt;!DOCTYPE> 在 XML 中是强制性的?

html - 使用Xpath,找到包含id为="userid"的输入框的最叶子表节点