Python 中的 Lxml 库与 XPath 用法

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 内容。

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 查询语法可以轻松提取信息。

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

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

# 创建新元素
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
  • 更多的数据类型处理,如日期时间处理
  • 数组和序列的操作
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)的验证功能,确保你的文档符合预定的标准。

# 创建一个 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 转换成另一种格式的有效方式。

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

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

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

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

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 提供了流式处理功能,避免一次性加载整个文档到内存。

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 解析器比较时更为明显。你还可以通过设置解析器选项来自定义解析行为。

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 的示例

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

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

  1. 选择最新的一本书
latest_book = root.xpath('//book[last()]')
print(latest_book[0].find('title').text)
  1. 按照年份升序排序书籍
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. 获取所有书籍的作者和标题
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. 获取书籍总数
total_books = len(root.xpath('//book'))
print(total_books)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/479688.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外卖点餐系统小程序

目录 开发前准备 项目展示项目分析项目初始化封装网络请求 任务1 商家首页 任务分析焦点图切换中间区域单击跳转到菜单列表底部商品展示 任务2 菜单列表 任务分析折扣信息区设计菜单列表布局请求数据实现菜单栏联动单品列表功能 任务3 购物车 任务分析设计底部购物车区域添加商…

彻底理解如何保证ElasticSearch和数据库数据一致性问题

一.业务场景举例 需求&#xff1a; 一个卖房业务&#xff0c;双十一前一天&#xff0c;维护楼盘的运营人员突然接到合作开发商的通知&#xff0c;需要上线一批热门的楼盘列表&#xff0c;上传完成后&#xff0c;C端小程序支持按楼盘的名称、户型、面积等产品属性全模糊搜索热门…

单片机将图片数组调出来显示MPU8_8bpp_Memory_Write

界面显示图片是很常见的需求&#xff0c;使用外挂的FLASH是最常用的方法。但是如果图片需求不大&#xff0c;比如说我们只要显示一个小图标&#xff0c;那么为了节省硬件成本&#xff0c;是不需要外挂一颗FLASH芯片的&#xff0c;我们可以将图标转成数组&#xff0c;存在单片机…

VS的安装和配置

目录 概述 安装Visual Studio 下载引导安装包 在线安装&#xff08;推荐&#xff09; 使用Visual Studio进行开发 创建项目 配置项目 项目 VS 解决方案&#xff08;重要&#xff09; 命名 完成项目创建 创建源文件 编写代码 VS项目目录的说明&#xff08;补充&…

linux模拟HID USB设备及wireshark USB抓包配置

文章目录 1. 内核配置2. 设备配置附 wireshark USB抓包配置 linux下模拟USB HID设备的简单记录&#xff0c;其他USB设备类似。 1. 内核配置 内核启用USB Gadget&#xff0c;使用fs配置usb device信息。 Device Drivers ---> [*] USB support ---><*> USB …

【C++】vector的使用

1. vector的构造 (constrator)构造函数声明 接口说明 vector(); (重点) 无参构造 vector (const vector& x); &#xff08;重点&#xff09; 拷贝构造 vector (InputIterator first, InputIterator last); 使用迭代器区间进行初始化构造 vector (size_type n, co…

Easy Excel 通过【自定义批注拦截器】实现导出的【批注】功能

目录 Easy Excel 通过 【自定义批注拦截器】实现导出的【批注】功能需求原型&#xff1a;相关数据&#xff1a;要导出的对象字段postman 格式导出对象VO 自定义批注拦截器业务代码&#xff1a; 拦截器代码解释&#xff1a;详细解释&#xff1a;格式优化&#xff1a; Easy Excel…

Qt/C++基于重力模拟的像素点水平堆叠效果

本文将深入解析一个基于 Qt/C 的像素点模拟程序。程序通过 重力作用&#xff0c;将随机分布的像素点下落并水平堆叠&#xff0c;同时支持窗口动态拉伸后重新计算像素点分布。 程序功能概述 随机生成像素点&#xff1a;程序在初始化时随机生成一定数量的像素点&#xff0c;每个…

矩阵重构——sortrows函数

s o r t r o w s sortrows sortrows函数依据某列的属性对其元素所在的行进行排序从而进行矩阵的排序 s o r t r o w s sortrows sortrows函数常用方法&#xff1a; 1. 1. 1. s o r t r o w s ( a , [ c 1 , c 2 ] ) sortrows(a,[c_1,c_2]) sortrows(a,[c1​,c2​])&#xff0c…

Linux之网络基础

网络发展 网络的发展可以从人与人之间的工作模式开始谈起, 人与人的工作模式反应了机器与机器的工作模式: 1. 独立模式: 在网络发展的早期计算机间处于独立模式, 计算机之间相互独立 最开始计算机之间是独立运行的, 数据之间的交互需要人用软盘等存储介质拷贝过去, 一般涉及…

【pyspark学习从入门到精通22】机器学习库_5

训练-验证分割 TrainValidationSplit 模型为了选择最佳模型&#xff0c;会对输入数据集&#xff08;训练数据集&#xff09;进行随机分割&#xff0c;分成两个子集&#xff1a;较小的训练子集和验证子集。分割只执行一次。 在这个例子中&#xff0c;我们还将使用 ChiSqSelect…

【Petri网导论学习笔记】Petri网导论入门学习(十一) —— 3.3 变迁发生序列与Petri网语言

目录 3.3 变迁发生序列与Petri网语言定义 3.4定义 3.5定义 3.6定理 3.5例 3.9定义 3.7例 3.10定理 3.6定理 3.7 有界Petri网泵引理推论 3.5定义 3.9定理 3.8定义 3.10定义 3.11定义 3.12定理 3.93.3 变迁发生序列与Petri网语言 对于 Petri 网进行分析的另一种方法是考察网系统…

IDEA:配置Serializable class without ‘serialVersionUID’ 找不到

在使用Java原生序列化的时候&#xff0c;serialVersionUID起到了一个类似版本号的作用&#xff0c;在反序列化的时候判断serialVersionUID如果不相同&#xff0c;会抛出InvalidClassException。 File -> Settings -> Editor -> Inspections -> 搜索 Serialization …

win10 禁止更新

一、winR 输入 regedit 二、输入注册列表路径&#xff1a; &#xff08;1&#xff09;计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings &#xff08;2&#xff09;按照格式&#xff0c;创建文件命名: FlightSettingsMaxPauseDays &#xff08;3&…

OpenAI Whisper 语音识别 模型部署及接口封装

环境配置: 一、安装依赖&#xff1a; pip install -U openai-whisper 或者&#xff0c;以下命令会从这个存储库拉取并安装最新的提交&#xff0c;以及其Python依赖项&#xff1a; pip install githttps://github.com/openai/whisper.git 二、安装ffmpeg&#xff1a; cd …

springboot视频网站系统的设计与实现(代码+数据库+LW)

摘 要 使用旧方法对视频信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在视频信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的视频网站系统管理员功…

安装QT6.8(MSVC MinGW)+QT webengine+QT5.15.2

本篇主要针对只使用过QT5的qmake&#xff0c;没有用过MSVC&#xff0c;VS的老同学。 建议一部分一部分安装&#xff0c;全部勾选安装遇到问题会中断&#xff0c;前功尽弃。 我自己需要的是QT5&#xff0c;编出的软件用在公司设备上。 QT6&#xff1a;建议也安装学习&#xf…

自动驾驶目标检测融合全貌

1、early fusion 早期融合&#xff0c;特点用到几何空间转换3d到2d或者2d到3d的转换&#xff0c;用像素找点云或者用点云找像素。 2、deep fusion 深度融合&#xff0c;也是特征级别融合&#xff0c;也叫多模态融合&#xff0c;如bevfusion范式 3、late fusion 晚融合&#x…

Microsoft Excel如何插入多行

1.打开要编辑的excel表&#xff0c;在指定位置&#xff0c;鼠标右键点击“插入”一行 2.按住shift键&#xff0c;鼠标的光标箭头会变化成如下图所示 3.一直按住shift键和鼠标左键&#xff0c;往下拖动&#xff0c;直至到插入足够的行

node.js基础学习-http模块-创建HTTP服务器、客户端(一)

http模块式Node.js内置的模块&#xff0c;用于创建和管理HTTP服务器。Node.js使用JavaScript实现&#xff0c;因此性能更好。 使用http模块创建服务器&#xff0c;我们建议使用commonjs模块规范&#xff0c;因为很多第三方的组件都使用了这种规范。当然es6写法也支持。 下面就是…