Python 中的 Lxml 库与 XPath 用法

news/2024/12/2 13:16:29/

Python 中的 Lxml 库与 XPath 用法

    • Python 中的 Lxml 库与 XPath 用法
      • Lxml
        • 安装 Lxml
        • 基础用法
          • 加载文档
          • 解析与查询
          • 创建新的 XML/HTML
        • 高级特性
          • 1. 复杂的 XPath 查询
          • 2. DTD 和 Schema 验证
          • 3. XSLT 变换
          • 4. 自定义命名空间
          • 5. 异常处理
          • 6. 大文件流式处理
          • 7. 并发和线程安全性
          • 8. 性能优化
      • XPath
        • 基础 XPath 语法
          • 选择元素
          • 谓词
        • 复杂查询
          • 组合条件
          • 函数
          • 节点数量
          • 排序
        • 实例演示
        • 性能注意事项
      • Lxml 和 XPath 的示例

Python 中的 Lxml 库与 XPath 用法

Lxml 是一个 Python 的第三方库,它提供了一套非常强大且高效的工具,用于处理 HTML 和 XML 文档。Lxml 结合了 libxml2 和 libxslt 库的功能,这意味着它不仅速度快,而且功能全面。对于 Web 抓取、文档解析和转换等工作,Lxml 是一个极佳的选择。

Lxml

安装 Lxml

可以通过 pip 来安装 Lxml:

pip install lxml
基础用法

Lxml 提供两种主要的数据结构: ElementTreeElementElementTree 表示整个文档,而 Element 则代表单个节点。

加载文档

你可以加载本地文件或者字符串形式的 HTML/XML 内容。

python">from lxml import etree# 从文件加载
tree = etree.parse('example.xml')# 从字符串加载
html_str = "<html><body><h1>Hello World!</h1></body></html>"
root = etree.fromstring(html_str)
解析与查询

使用 XPath 查询语法可以轻松提取信息。

python"># 获取所有 h1 元素
elements = tree.xpath('//h1')# 输出元素文本
for elem in elements:print(elem.text)
创建新的 XML/HTML

Lxml 支持创建全新的 XML 或者 HTML 文件。

python"># 创建新元素
elem = etree.Element("greeting")
elem.text = "Hello"
sub_elem = etree.SubElement(elem, "name")
sub_elem.text = "World"# 将元素转化为字符串输出
etree.tostring(elem, pretty_print=True)
高级特性

Lxml 是一个极其丰富的库,为处理 XML 和 HTML 提供了大量的高级功能。以下是 Lxml 提供的一些关键特性和使用案例,这些特性让它成为一个非常强大且多功能的工具包:

1. 复杂的 XPath 查询

除了基本的 XPath 功能外,Lxml 还支持更复杂的 XPath 2.0 特性,比如:

  • 函数调用,如 substring, starts-with, normalize-space
  • 更多的数据类型处理,如日期时间处理
  • 数组和序列的操作
python">from lxml import etree# 检查是否以特定字符开头
results = tree.xpath("//element[starts-with(@attr, 'prefix')]")# 字符串截取
value = tree.xpath("string(/path/to/node)[substring(., 1, 5)]")# 正则表达式匹配
matches = tree.xpath("//element[re:test(@attr, 'pattern')]")
2. DTD 和 Schema 验证

Lxml 提供了 DTD(Document Type Definition)和 Schema(如 XML Schema, Relax NG)的验证功能,确保你的文档符合预定的标准。

python"># 创建一个 DTD 或 Schema 验证器
schema = etree.DTD('my.dtd')
schema = etree.XMLSchema(etree.parse('myschema.xsd'))# 验证文档
if not schema.validate(tree):raise ValueError("Document is not valid against the provided DTD or Schema.")
3. XSLT 变换

Lxml 支持使用 XSLT 对 XML 文档进行转换,这是一种将源 XML 转换成另一种格式的有效方式。

python"># 加载 XSLT 文件
transformer = etree.XSLT(etree.parse('stylesheet.xsl'))# 应用转换
new_doc = transformer(etree.parse('source.xml'))
4. 自定义命名空间

在处理带有命名空间的 XML 文档时,Lxml 提供了简洁的方式来进行处理。

python">ns = {'n': 'http://www.example.com/mynamespace'}# 使用命名空间查询
elements = tree.xpath('//n:element', namespaces=ns)
5. 异常处理

Lxml 包含了丰富的异常类,可以让你更准确地捕捉和处理 XML/HTML 解析过程中的问题。

python">from lxml.etree import ParseErrortry:doc = etree.fromstring('<bad_xml>')
except ParseError as e:print(f"Parse error at line {e.lineno}: {e.message}")
6. 大文件流式处理

对于大型文件,Lxml 提供了流式处理功能,避免一次性加载整个文档到内存。

python">context = etree.iterparse('largefile.xml', events=('end',), huge_tree=True)
for event, elem in context:# 这里可以安全地处理每个元素process_element(elem)elem.clear()while elem.getprevious() is not None:del elem.getparent()[0]del context
7. 并发和线程安全性

Lxml 在设计上考虑了线程安全,并允许你在多线程环境中使用,这对于大规模数据处理特别有用。

8. 性能优化

Lxml 由 C 实现,在速度和资源管理方面进行了优化,尤其是当与其他纯 Python 解析器比较时更为明显。你还可以通过设置解析器选项来自定义解析行为。

python">parser = etree.XMLParser(remove_comments=True, recover=True)
tree = etree.parse('large_file.xml', parser=parser)

总之,Lxml 是 Python 生态系统中处理 XML 和 HTML 数据的一个强大库,无论是用于解析、生成、验证还是变换,它都表现出色。通过上述基础和进阶应用的学习,你应该能够灵活运用 Lxml 来解决复杂的数据处理任务。

XPath

XPath 是一种在 XML 文档中查询和定位元素和属性的强大语言,但它同样可以应用于 HTML 文档。XPath 的表达式可以相当复杂,涵盖了广泛的查询需求。下面是 XPath 的一些常用操作和高级用法汇总:

基础 XPath 语法
选择元素
  • //:从根节点开始搜索所有子孙节点
  • /:绝对路径
  • .:当前节点
  • ..:父节点
  • *:任何元素
  • @:属性选择器
  • ancestor:祖先节点
  • attribute:属性
  • child:子节点
  • descendant:后代节点
  • following-sibling:后续同级节点
  • preceding-sibling:前面的同级节点
谓词
  • [1]:选择指定位置的节点
  • [contains(text(), 'search-text')]:包含文本的节点
  • [@class='classname']:具有特定属性的节点
复杂查询
组合条件
  • and / or:逻辑运算符连接多个条件
  • not():否定条件
函数
  • string-length():计算字符串长度
  • normalize-space():移除首尾空格,压缩内部空白
  • concat():拼接字符串
  • contains(string, substring):检查子字符串
  • starts-with(string, prefix):检查字符串前缀
  • ends-with(string, suffix):检查字符串后缀
节点数量
  • count(node-set):统计节点数目
排序
  • sort():按顺序排列结果
实例演示

假设有一个 XML 文档如下:

<books><book genre="fiction"><author>John Doe</author><title>The Great Novel</title><year>2020</year></book><book genre="non-fiction"><author>Jane Smith</author><title>A Guide to Cooking</title><year>2019</year></book>
</books>

选择所有书名

//book/title

选择第一本书的作者

/book[1]/author

找到年份大于等于 2020 的所有书

//book[year >= 2020]

查找标题包含 “Guide” 的书

//book[contains(title, 'Guide')]

获取具有非小说类型的书的作者名字

//book[@genre != 'fiction']/author

按出版年份降序排序的书籍列表

//book | sort-by(., year descending)
性能注意事项

虽然 XPath 非常强大,但在处理大数据量时,应该谨慎使用,因为某些查询可能涉及遍历大量节点,从而影响性能。为了提高效率,尽量减少重复扫描,使用索引或其他技术,特别是在大型文档中进行搜索时。

总之,XPath 提供了一个功能丰富且直观的方式来操纵和查询 XML 和 HTML 文档。掌握这些基本和高级用法可以使你更加熟练地处理各种结构化文档的分析和检索工作。

Lxml 和 XPath 的示例

python">from lxml import etreexml_data = """
<books><book genre="fantasy"><author>Tolkien</author><title>The Hobbit</title><year>1937</year></book><book genre="science-fiction"><author>Asimov</author><title>I, Robot</title><year>1950</year></book><book genre="horror"><author>King</author><title>The Shining</title><year>1977</year></book>
</books>
"""# 解析 XML 字符串
root = etree.fromstring(xml_data)

现在我们可以编写一系列示例,对应不同的 XPath 查询:

  1. 选择所有 <title> 元素
python">titles = root.xpath('//title')
for t in titles:print(t.text)
  1. 获取第一本书的 <year>
python">first_year = root.xpath('//book/year')[0].text
print(first_year)
  1. 找到类型为科幻的书
python">sci_fi_books = root.xpath('//book[@genre="science-fiction"]')
for book in sci_fi_books:print(book.find('title').text)
  1. 查找标题包含单词 “The” 的所有书
python">the_books = root.xpath('//book[title[translate(text(),"THE","the") = "the"]]')
for book in the_books:print(book.find('title').text)

注意上面使用 translate() 函数将标题转换成小写以便不区分大小写的比较。

  1. 选择最新的一本书
python">latest_book = root.xpath('//book[last()]')
print(latest_book[0].find('title').text)
  1. 按照年份升序排序书籍
python">sorted_books = sorted(root.findall('.//book'), key=lambda b: int(b.find('year').text))
for book in sorted_books:print(book.find('title').text)
  1. 获取所有书籍的作者和标题
python">authors_and_titles = root.xpath('//book/(author|title)')
for i in range(0, len(authors_and_titles), 2):author = authors_and_titles[i].texttitle = authors_and_titles[i+1].textprint(f"{author} wrote {title}")
  1. 获取书籍总数
python">total_books = len(root.xpath('//book'))
print(total_books)

http://www.ppmy.cn/news/1551763.html

相关文章

vscode的markdown扩展问题

使用vscode编辑markdown文本时&#xff0c;我是用的是Office Viewer(Markdown Editor)这个插件 今天突然发现不能用了&#xff0c;点击切换编辑视图按钮时会弹出报错信息&#xff1a; command office.markdown.switch not found 在网上找了很久发现没有有关这个插件的文章………

后端 Java发送邮件 JavaMail 模版 20241128测试可用

配置授权码 依赖 <dependency><groupId>javax.mail</groupId><artifactId>javax.mail-api</artifactId><version>1.5.5</version> </dependency> <dependency><groupId>com.sun.mail</groupId><artifa…

STM32 BootLoader 刷新项目 (十二) Option Byte之FLASH_OPTCR-命令0x58

STM32 BootLoader 刷新项目 (十二) Option Byte之FLASH_OPTCR-命令0x58 STM32F407芯片的OPTION Byte全面解析 STM32F407芯片是STMicroelectronics推出的一款功能强大的微控制器&#xff0c;广泛应用于工业控制、通信和消费电子等领域。其中&#xff0c;OPTION Byte&#xff0…

xiaolin coding 图解网络笔记——IP 篇

1. IP 基本认识 IP 在 TCP/IP 模型中的第三层&#xff0c;网络层。网络层的主要作用是&#xff1a;实现主机与主机之间的通信&#xff0c;也叫点对点&#xff08;end to end&#xff09;通信。 MAC&#xff08;数据链路层&#xff09;的作用是【直连】的两个设备之间的通信&a…

MFC图形函数学习12——位图操作函数

位图即后缀为bmp的图形文件&#xff0c;MFC中有专门的函数处理这种格式的图形文件。这些函数只能处理作为MFC资源的bmp图&#xff0c;没有操作文件的功能&#xff0c;受限较多&#xff0c;一般常作为程序窗口界面图片、显示背景图片等用途。有关位图操作的步骤、相关函数等介绍…

预训练模型与ChatGPT:自然语言处理的革新与前景

目录 一、ChatGPT整体背景认知 &#xff08;一&#xff09;ChatGPT引起关注的原因 &#xff08;二&#xff09;与其他公司的竞争情况 二、NLP学习范式的发展 &#xff08;一&#xff09;规则和机器学习时期 &#xff08;二&#xff09;基于神经网络的监督学习时期 &…

手机上怎么拍证件照,操作简单且尺寸颜色标准的方法

在数字化时代&#xff0c;手机已成为我们日常生活中不可或缺的一部分。它不仅是通讯工具&#xff0c;更是我们拍摄证件照的便捷利器。然而&#xff0c;目前证件照制作工具鱼龙混杂&#xff0c;很多打着免费名号的拍照软件背后却存在着泄漏用户信息、照片制作不规范导致无法使用…

PDF本地显示正常,但是上传系统后,预览显示乱码

问题&#xff1a;PDF本地显示正常&#xff0c;但是上传系统后&#xff0c;预览显示乱码 原因&#xff1a;猜测可能是某些字体或资源的缺失&#xff0c;导致PDF在线上预览显示乱码。经过搜索找到原因&#xff1a;原因是PDF缺少一些嵌入字体1。 解决思路&#xff1a; 使用Adobe…