当使用lxml库的XPath解析带有命名空间(namespace)的HTML或XML文档时,经常会遇到XPathEvalError
错误。这是因为XPath表达式需要正确处理命名空间才能匹配到元素。
带命名空间的文档如XHTML或某些XML文档,其标签形式为<ns:tag>
,直接使用普通XPath表达式如//div
无法匹配。
from lxml import etree
html = """<html xmlns="http://www.w3.org/1999/xhtml">
<body><div>Content</div></body></html>"""
tree = etree.fromstring(html)
# 使用通配符匹配任何命名空间下的div元素
result = tree.xpath('//*[local-name() = "div"]')
print(result) # 输出匹配的div元素
from lxml import etree
html = """<html xmlns="http://www.w3.org/1999/xhtml">
<body><div>Content</div></body></html>"""
tree = etree.fromstring(html)
# 创建命名空间字典
ns = {'x': 'http://www.w3.org/1999/xhtml'}
# 在XPath中使用注册的前缀
result = tree.xpath('//x:div', namespaces=ns)
print(result)
from lxml import etree
html = """<html xmlns="http://www.w3.org/1999/xhtml">
<body><div>Content</div></body></html>"""
# 移除命名空间
html_no_ns = html.replace('xmlns="http://www.w3.org/1999/xhtml"', '')
tree = etree.fromstring(html_no_ns)
result = tree.xpath('//div')
print(result)
如果处理的是HTML而非严格XML,可以使用lxml.html
模块,它会自动处理命名空间问题:
from lxml import html
html_content = """<html xmlns="http://www.w3.org/1999/xhtml">
<body><div>Content</div></body></html>"""
tree = html.fromstring(html_content)
result = tree.xpath('//div')
print(result)
希望这些解决方案能帮助你顺利处理带命名空间的HTML/XML文档解析问题!