Python 中的 Lxml 库与 XPath 用法

ops/2024/11/28 19:51:58/

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/ops/137456.html

相关文章

鸿蒙NEXT开发案例:文字转拼音

【引言】 在鸿蒙NEXT开发中&#xff0c;文字转拼音是一个常见的需求&#xff0c;本文将介绍如何利用鸿蒙系统和pinyin-pro库实现文字转拼音的功能。 【环境准备】 • 操作系统&#xff1a;Windows 10 • 开发工具&#xff1a;DevEco Studio NEXT Beta1 Build Version: 5.0.…

Spring Boot的JdbcTemplate实现“不存在即插入,存在即更新”

在 Java 中实现【不存在即插入&#xff0c;存在即更新】 INSERT ... ON DUPLICATE KEY UPDATE Spring Boot 的 JdbcTemplate 实现 INSERT ... ON DUPLICATE KEY UPDATE 如果你使用的是 Spring Boot 的 JdbcTemplate&#xff0c;可以这样实现&#xff1a; 代码示例 Autowire…

【八股文】小米

文章目录 一、vector 和 list 的区别&#xff1f;二、include 双引号和尖括号的区别&#xff1f;三、set 的底层数据结构&#xff1f;四、set 和 multiset 的区别&#xff1f;五、map 和 unordered_map 的区别&#xff1f;六、虚函数和纯虚函数的区别&#xff1f;七、extern C …

安装Docker的时候报错

在一台新的虚拟机里安装docker的时候报错了&#xff0c;执行命令如下 yum install -y docker-ce docker-ce-cli containerd.io报错信息如下&#xff1a; Error downloading packages:3:docker-ce-27.0.0~rc.2-1.el7.x86_64: [Errno 256] No more mirrors to try.在网上查询了…

html+css+js打字游戏网页

1. 效果 2. html代码 <!doctype html> <html><head><meta charset"utf-8" /><title>打字练习</title><!--引入第三方动画库--><link rel"stylesheet" href"animate.css"><style>html {h…

一次SQL注入深入利用

1. 在寻找某处的资产时找到一个查询的页面&#xff1a; https://xxxxxxxxxxx/index.php/all 随便查询一下&#xff0c;然后抓包: 测试发现这里存在注入&#xff1a; 由于有报错信息&#xff0c;首先考虑报错注入&#xff1a; Poc&#xff1a; andupdatexml(0x7e,concat(0x7e,…

计算机网络----基本概念

基本概念 在这一章从整体上介绍计算机网络的概况, 为后续的学习搭建起整体的框架; 介绍计算机网络中的基础术语和概念; 什么是因特网 『 因特网 』是一个世界范围内互联了数以亿计的计算设备的计算机网络; 因特网具体构成 因特网互联了数以亿计的计算设备, 这些设备被称为…

【软考速通笔记】系统架构设计师⑤——软件工程基础知识

文章目录 一、前言二、基础知识点2.1 软件危机2.2 软件生命周期 三、软件过程模型&#xff08;论文&#xff09;3.1 瀑布模型3.2 原型模型3.3 螺旋模型3.4 敏捷模型3.5 软件统一过程模型3.6 软件成熟度模型3.7 软件成熟度模型集成 四、需求工程五、软件测试5.1 根据程序执行状态…