前言 这里只是是一本lxml的简单修炼手册
一、lxml 概述 1.1 什么是 lxml lxml 是 Python 中一个高效、功能丰富 的 XML 和 HTML 处理库,结合了:
libxml2 的高性能
ElementTree 的简单 API
强大的 XPath 和 XSLT 支持
1.2 核心特性
支持 XML 和 HTML 解析
完整的 XPath 1.0 实现
XSLT 1.0 转换支持
基于 ElementTree 的 API
高性能解析(比内置 xml 模块快 10-100 倍)
优雅的错误恢复机制
二、安装与基本使用 2.1 安装
2.2 基础解析示例 1 2 3 4 5 6 7 8 9 10 from lxml import etreexml_data = "<root><child>Text</child></root>" root = etree.fromstring(xml_data) from lxml import htmlhtml_data = "<html><body><div>Content</div></body></html>" tree = html.fromstring(html_data)
三、XML 处理 3.1 元素操作 1 2 3 4 5 6 7 8 9 10 11 12 root = etree.Element("root" ) child = etree.SubElement(root, "child" ) child.text = "Text content" child.set ("id" , "123" ) print (root.tag) print (child.text) print (child.get("id" ))
3.2 元素遍历 1 2 3 4 5 6 7 8 9 10 11 for element in root: print (element.tag) for element in root.iter (): print (element.tag) for child in root.iter ("child" ): print (child.text)
四、HTML 处理 4.1 HTML 解析与修复 1 2 3 4 5 6 7 broken_html = "<div><p>Paragraph</div>" tree = html.fromstring(broken_html) fixed_html = etree.tostring(tree, pretty_print=True ).decode() print (fixed_html)
4.2 提取链接与文本 1 2 3 4 5 6 7 8 9 10 11 12 html_content = """ <a href="/page1">Link 1</a> <a href="/page2">Link 2</a> """ tree = html.fromstring(html_content) links = tree.xpath('//a/@href' ) texts = [a.text for a in tree.xpath('//a' )]
五、XPath 表达式 5.1 基本语法
表达式
说明
示例
nodename
选择节点
//div
/
从根节点选择
/root/child
//
选择任意位置
//div
.
当前节点
./child
..
父节点
../parent
@
选择属性
//@id
*
通配符
//*
5.2 实用示例 1 2 3 4 5 6 7 8 9 10 11 divs = tree.xpath('//div[@class]' ) first_p = tree.xpath('//p[1]' ) elements = tree.xpath('//*[contains(text(), "Search")]' ) elements = tree.xpath('//a[starts-with(@href, "/category")]' )
六、XSLT 转换 6.1 基本转换流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <data > <item > Apple</item > <item > Banana</item > </data > <xsl:stylesheet version ="1.0" xmlns:xsl ="http://www.w3.org/1999/XSL/Transform" > <xsl:template match ="/" > <fruits > <xsl:apply-templates /> </fruits > </xsl:template > <xsl:template match ="item" > <fruit > <xsl:value-of select ="." /> </fruit > </xsl:template > </xsl:stylesheet >
1 2 3 4 5 6 7 8 dom = etree.parse("input.xml" ) xslt = etree.parse("transform.xsl" ) transform = etree.XSLT(xslt) result = transform(dom) print (str (result))
七、高级功能 7.1 解析器选项 1 2 3 4 5 6 7 8 9 parser = etree.XMLParser( remove_blank_text=True , resolve_entities=False , huge_tree=True ) tree = etree.parse("large.xml" , parser)
7.2 增量解析(处理大型文件) 1 2 3 4 5 6 7 8 9 10 11 12 13 context = etree.iterparse("large.xml" , events=("start" , "end" )) for event, elem in context: if event == "start" and elem.tag == "item" : pass elif event == "end" and elem.tag == "item" : print (elem.text) elem.clear() while elem.getprevious() is not None : del elem.getparent()[0 ]
7.3 HTML 表单处理 1 2 3 4 5 6 7 8 9 10 11 tree = html.fromstring("<form><input name='user' value='admin'></form>" ) form = tree.forms[0 ] print (form.fields['user' ]) form.fields['user' ] = 'newuser' print (form.form_values())
八、性能优化 8.1 高效处理技巧
使用迭代解析 :处理大型文件时避免内存溢出
1 2 3 for _, element in etree.iterparse("large.xml" , tag="item" ): process(element) element.clear()
编译XPath表达式 :重复使用时提升性能
1 2 find_items = etree.XPath("//items/item" ) items = find_items(tree)
选择性解析 :只加载需要的部分
1 2 items = etree.parse("data.xml" ).xpath("//target-element" )
8.2 与内置库对比
特性
lxml
xml.etree.ElementTree
性能
⭐⭐⭐⭐
⭐⭐
XPath支持
完整1.0
有限子集
HTML处理
优秀
不支持
错误恢复
强大
有限
内存占用
较低
较高
依赖
C扩展
纯Python
九、常见问题解决 9.1 命名空间处理 1 2 3 4 5 6 7 8 9 xml = """<root xmlns:ns="http://example.com"> <ns:item>Value</ns:item> </root>""" tree = etree.fromstring(xml) ns = {"ns" : "http://example.com" } items = tree.xpath("//ns:item" , namespaces=ns)
9.2 编码问题 1 2 3 4 5 6 parser = etree.XMLParser(encoding="iso-8859-1" ) tree = etree.parse("data.xml" , parser) result = etree.tostring(root, encoding="utf-8" , xml_declaration=True )
9.3 错误处理 1 2 3 4 5 try : tree = etree.parse("invalid.xml" ) except etree.XMLSyntaxError as err: print (f"解析错误: {err.message} " ) print (f"位置: 行 {err.lineno} , 列 {err.offset} " )
十、最佳实践 10.1 安全建议
禁用实体解析(避免XXE攻击)
1 parser = etree.XMLParser(resolve_entities=False )
谨慎处理用户提供的XSLT/XPath
验证输入数据格式
10.2 开发实践
优先使用XPath :比手动遍历更简洁高效
利用HTML修复功能 :处理不规范的网页内容
使用CSS选择器 (需要lxml.cssselect)
1 2 3 from lxml.cssselect import CSSSelectorsel = CSSSelector('div.content > p' ) paragraphs = sel(tree)
组合使用工具 :
1 2 3 from bs4 import BeautifulSoupsoup = BeautifulSoup(html, "lxml" )
版权声明: 此文章版权归曦曦所有,如有转载,请注明来自原作者