使用 lxml 解析嵌套 HTML 结构时,最推荐的处理方向是始终使用etree.HTML()或etree.HTMLParser()加载内容,并在查询当前节点的子元素时在 XPath 表达式前加点(如.//span)。适用场景为 Python 爬虫数据提取,最重要的风险边界是错误使用 XML 解析器会导致不规范 HTML 解析中断,且忽略相对路径符号会导致从文档根重新搜索而非当前节点。
先说结论:使用 lxml 解析嵌套结构的关键在于解析器选择与相对路径定位,确保容错性与上下文正确。
- 适合:Python 爬虫解析嵌套标签、提取文本或属性。
- 先看:加载方法是否用了
etree.HTML()而非XMLParser()。 - 建议:在已选节点上查子节点时,XPath 必须用
.开头限定范围。
命令速用版
安装 lxml 库并加载 HTML 字符串的基本命令如下:
pip install lxmlfrom lxml import etree
html_content = '<html><body><div><span>Text</span></div></body></html>'
tree = etree.HTML(html_content)
result = tree.xpath('//div/span/text()')为什么会这样
XPath 在 lxml 里取不到嵌套子节点,主要是因上下文定位错误或解析器不兼容。
不加.会从文档根查找,应使用.//span;且 HTML 解析须用etree.HTMLParser()而非XMLParser()。HTML 常含不规范标签,XML 解析器会报错或截断,而 HTML 解析器能容错解析。
分步处理
按以下步骤完成嵌套结构解析:
- 安装库:运行
pip install lxml确保环境支持。 - 加载内容:使用
etree.HTML(html_string)或etree.parse(url, etree.HTMLParser())加载,避免用XML()处理网页源码。 - 定位父节点:先用 XPath 选中父元素,如
//div[@class="item"]。 - 查找子节点:对每个父节点调用
.xpath(".//span"),注意路径前加.。 - 提取数据:文本内容显式用
/text(),属性用/@href。
怎么验证是否生效
通过打印列表长度和内容确认解析结果:
- 检查返回对象是否为列表,即使只匹配一个节点。
- 打印
len(result)确认非零。 - 打印
result[0]查看具体文本或属性值。 - 如果遇到
XMLSyntaxError,检查是否误用了 XML 解析器。
常见坑
- 路径未加点:在父节点对象上查子节点时,写成
//span会从全文档搜索,应写.//span。 - 解析器选错:用
etree.XML()处理 HTML 会导致标签不闭合时报错。 - 忽略返回列表:xpath 返回的是列表,直接取值会报错,需先判断长度。
- 大小写敏感:XPath 里标签名通常需小写,即使源文件中有大写。
常见问题
为什么 xpath 在 lxml 里取不到嵌套子节点?
问题出在 XPath 的上下文定位,忘了加.会从整个文档根重新查,而不是从当前节点往下找。
怎么提取标签的属性值?
属性要用/@xxx语法,例如//a/@href,返回结果也是列表。
需要安装什么 Python 库?
目前被推荐的 Python binding 是 lxml,可以通过pip install lxml安装。
参考来源
- Python 爬虫怎么用 XPath_lxml 库与 XPath 语法提取嵌套层级节点数据
- Python 实例详解:使用 XPath 解析 HTML/XML 数据
- Python 中利用 xpath 解析 HTML - whgiser - 博客园
- python 使用 xpath 解析 html
- Python 爬虫中如何使用 xpath 解析 HTML