lxml库的基本使用

Python之lxml模块的使用:

  • 1. 认识lxml
  • 2. lxml中基本使用
    • 2.1 安装并导入lxml模块
    • 2.2 节点操作:
    • 2.3 属性操作:
    • 2.4 文本操作
    • 2.5 xml文件解析与序列化
    • 2.6 lxml命名空间的处理
  • 3. 使用lxml解析xml案例
  • 4. 使用lxml生成一个xml文件案例:
  • 5. 补充:xPath语法
    • 5.1 节点选择语法:
    • 5.2 节点修饰语法:
    • 5.3 谷歌浏览器xpath helper插件的安装和使用

1. 认识lxml

lxml是一款高性能的Python XML库,主要用来解析及生成xml和html文件(解析、序列化、转换)。其天生支持Xpath1.0、XSLT1.0、定制元素类,甚至 python 风格的数据绑定接口。lxml基于Cpython实现,其底层是libxml2和libxslt两个C语言库。因此具有较高的性能。

官方文档:https://lxml.de/

2. lxml中基本使用

在lxml中,lxml.etree模块是最常用的HTML、XML文档解析模块。其中lxml.etree.Element是处理xml的一个核心类,Element对象可以直观的理解为是XML中的节点。使用Element类,可以实现对XML节点、节点属性、节点内文本的操作。

2.1 安装并导入lxml模块

pip install lxml
from lxml import etree

2.2 节点操作:

1.创建节点(创建Element对象):

root = etrre.Element('root')
print(root)

2.获取节点名称

print(root.tag)

3.添加子节点

添加子节点的方法有三种:1、直接使用SubElement方法添加子节点。2、创建一个Element对象,使用append的方法将该对象追加到父节点中。3、创建一个Element对象,使用insert方法,将对象添加到父节点指定位置。

  • 使用SubElement方法添加:
child_sub = etree.SubElement(root, 'child_sub')
  • 使用append方法添加:
child_append = etree.Element('child_append')
root.append(child_append)
  • 使用insert方法添加:
child_insert = etree.Element('child_insert')
root.insert(0, child_append)  #  第一个参数为添加的位置,第二个参数为添加的Element对象

4.删除子节点:

可以使用remove()方法来删除指定子节点。使用clear()方法来清空所有子节点

root.remove(child_sub)  # 删除名字为child_sub节点
root.clear()  # 清空root的所有子节点

5.访问节点

在Element对象中,访问节点的方法有多种。

  • 可以通过列表的方式来方位节点。
  • 可以通过getparent()等方法来访问节点。
  • 可以通过xpath语法来定位指定节点(暂不介绍)

(1) 通过列表的方式来访问节点:

child_sub = root[0]  # 通过下标来访问子节点
child_sub = root[0: 1][0]  # 通过切片的方式来访问节点
for c in root:  # 通过遍历来获取所有节点print(c.tag)c_append_index = root.index(child_append)  # 获取节点的索引
print(len(root))  # 获取子节点的数量

(2) 通过方法来访问节点:

  • 获取父节点:getarent()
  • 获取所有子节点:getchildren()
  • 获取根节点:getroot()
  • findall():返回所有匹配的元素,返回列表
  • find():返回匹配到的第一个元素
print(child_sub.getparent().tag)  # 查询父节点
print(root.getchildren())  # 查询所有子节点
print(root.getroot())  # 获取根节点
print(root.find('b'))  # 查询第一个b标签
print(root.findall('.//b'))  # 查询所有b标签

2.3 属性操作:

在Element中,节点的属性是以字典的形式存储的。

创建属性:

创建属性的方式有两种。1、在创建节点的时候创建属性。2、使用set()方法创建属性。

root = etree.Element('root', language='中文')  # 创建节点时创建属性root.set('hello', 'python')  # 使用set方法为root节点添加属性

获取属性:

print(root.get('language'))  # 使用get方法获取属性
print(root['language'])
print(root.keys())
print(root.values())
print(root.items())

修改属性:

root['language'] = 'English'

2.4 文本操作

在lxml中访问xml文本的方式有多种,可以使用text、tail属性的方式访问文本。也可以使用xpath语法访问文本。这里只介绍使用text和tail获取和设置文本的属性的方法。xpath后面会具体介绍。

text和tail属性 的区别:

xml中标签一般是成对出现的。但在HTML中则可能会出现单标签,如<html><body>text<br/>tail</body></html>

  • text属性用于成对便签的读取和设置
  • tail属性用于单一标签的读取和设置
html = etree.Element('html')
body = etree.SubElement(html, 'body')
body.text = 'text'  # 给body标签内写入text文本内容br = etree.SubElement('body', 'br')
br.tail = 'tail'  # 在br标签中写入tail文本内容

2.5 xml文件解析与序列化

1. xml文件解析的方法:
xml文件解析的方法有多种,常用的有fromstring、XML、HTML、parse。其中XML和HTML的参数既可以是字符串、也可以是二进制的字节码。

  • fromstring、XML、parse:返回的是一个Element对象,是一个节点。主要用于解析文档碎片。

  • parse(): 返回值是一个ElementTree类型的对象,完整的xml树结构。parse主要用来解析完整的文档,而不是Element对象。

  • 参数:
    打开的文件或文件类型对象(建议以二进制形式打开
    文件名或字符串
    HTTP或者FTP的url。

    注意:从文件名或者url解析通常比从文件对象解析要快

xml_data = '<root>data</root>'# fromstring
root_str = etree.formstring(xml_data)
print(root_str.tag)# XML
root_xml = etree.XML(xml_data)
print(root_xml.tag)# HTML,如果没有<html>和<body>标签,则会自动补上root_html = etree.HTML(xml_data)print(root_html.tag)# parse中的参数应该是一个完整的xml或html,同样返回值是一个ElementTree类型的对象,完整的xml树结构。parse主要用来解析完整的文档。
tree =etree.parse('text')   #文件解析成元素树
root = tree.getroot()      #获取元素树的根节点
print etree.tostring(root, pretty_print=True)

2. xml文件序列化的方法:

我们在生成一个xml文件是有两种方式:1、将Element对象转换成一个xml字符串,然后将其写入到文件中。2、使用ElementTreee对象中的write()方法直接将xml写入文件。

root = '<root>data</root>'# 将Element对象转换成xml字符串写入文件
root_str = element.tostring(root, pretty_print=True, xml_declartion=True, encoding='utf-8')
with open('text.xml', 'w', encoding='utf-8') as f:f.write(root_str)# 将节点(Element对象)转为ElementTree对象。
tree = etree.ElementTree(root)
tree.write('text.xml', pretty_print=True, xml_declartion=True, encoding='utf-8')

参数含义:

  • 第一个参数是xml保持的路径(包括文件名)
  • pretty_print:是否格式化xml(美化)
  • xml_declaration:是否写入xml声明,就是xml中开头第一行文字。
  • encoding:编码格式

补充:ElementTree对象可理解为一个完整的XML树,每个节点都是一个Element对象。而ElementPath则相当于XML中的XPath。用于搜索和定位Element元素。


2.6 lxml命名空间的处理

什么是命名空间?https://www.w3school.com.cn/xml/xml_namespaces.asp

带有命名空间的xml解析处理:

from lxml import etreestr_xml = """
<A xmlns="http://This/is/a/namespace"><B>dataB1</B><B>dataB2</B><B><C>datac</C></B>
</A>
"""xml = etree.fromstring(str_xml)  # 解析字符串
ns = xml.nsmap  # 获取命名空间
print(ns)
print(ns[None])>>> {None: 'http://This/is/a/namespace'}
>>> http://This/is/a/namespacens = xml.nsmap[None]  # 获取命名空间xmlns# 1. 使用findall方法查找指定节点。
for item in xml.findall(f'{ns}b')print(item.text)# 2. 使用xpath语法加命名空间查找指定节点
ns = {'x':root.nsmap[None]}  # 获取命名空间
b = root.xpath("//x:B", namespaces=ns)
print(b)C = root.xapth("//x:B/X:C", namespaces=ns)
print(c)

注意:当xml携带有命名空间(xmlns)的时候,在查找节点时,每一级节点都需要加上命名空间。如果不携带命名空间,是无法查询到该节点的。
除此之外处理命名空间还有一个非常shao的方法,即将所有的命名空间都替换为空,将其当成普通的节点进行处理。

参考:https://blog.csdn.net/rhx_qiuzhi/article/details/105345624


3. 使用lxml解析xml案例

(1)导入lxml 的 etree 库

from lxml import etree

(2)利用etree.HTML,将html字符串(bytes类型或str类型)转化为Element对象,Element对象具有xpath的方法,返回结果的列表

html = etree.HTML(text)
ret_list = html.xpath("xpath语法规则字符串")

(3)xpath方法返回列表的三种情况

  • 返回空列表:根据xpath语法规则字符串,没有定位到任何元素
  • 返回由字符串构成的列表:xpath字符串规则匹配的一定是文本内容或某属性的值
  • 返回由Element对象构成的列表:xpath规则字符串匹配的是标签,列表中的Element对象可以继续进行xpath
from lxml import etree
text = '''
<div><ul><li class="item-1"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0">a href="link5.html">fifth item</a></ul>
</div>
'''html = etree.HTML(text)  # 也可以使用XML和fromstring方法# 获取所有的class属性为item-1的href属性
href_list = html.xpath('//li[@class="item-1"]/a/@href')
# 获取所有的class属性为item-1的text内容
text_list = html.xpath('//li[@class="item-1"]/a/text()')# 组装成字典
for href, title in zip(href_list, title_list):print({f'{href}': f'{title}'})

注意:lxml.etree.HTML(html_str)方法可以自动补全不完整的标签。


4. 使用lxml生成一个xml文件案例:

from lxml import etree# 创建element对象
root = etree.Element('root')
print(root.tag)# 添加子节点
child_sub = etree.SubElement(root, 'child_sub')child = etree.Element('child')
child_append = root.append(child)  # 通过append向root节点里面追加子节点
child_insert = root.insert(0, child)  # 通过insert向root节点开始的位置添加子节点# 3.删除子节点
# root.remove(child2)# 4.删除所有子节点
# root.clear()# 5.以列表的方式操作子节点
print(len(root))
print root.index(child)  # 索引号# 6.生成xml字符串写入xml文件
# 将Element对象转换成xml字符串写入文件
root_str = etree.tostring(root, pretty_print=True, xml_declaration=True, encoding='utf-8')
with open('text.xml', 'wb') as f:f.write(root_str)# 将节点(Element对象)转为ElementTree对象。
tree = etree.ElementTree(root)
tree.write('text.xml', pretty_print=True, xml_declartion=True, encoding='utf-8')

参考链接:https://blog.csdn.net/ydw_ydw/article/details/82227699


5. 补充:xPath语法

  • XPath (XML Path Language) 是一门在 HTML\XML 文档中查找信息的语言,可用来在 HTML\XML文档中对元素和属性进行遍历
  • W3School官方文档:http://www.w3school.com.cn/xpath/index.asp
  • 提取xml、html中的数据一般需要将lxml模块和xpath语法配合使用

5.1 节点选择语法:

xpath定位节点以及提取属性或文本内容的语法:

表达式描述
nodename选中该元素。
/从根节点选取、或者是元素和元素间的过渡。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点。
..选取当前节点的父节点。
@选取属性。
text()选取文本。

注意:@符号出现在末尾时,用来提取属性;出现在[]中时是用来匹配属性

选取未知节点的语法:
可以通过通配符来选取未知的html、xml的元素

通配符描述
*匹配任何元素节点。
node()匹配任何类型的节点。
  • 全部的标签://*
  • 全部的属性://node()

5.2 节点修饰语法:

可以根据标签的属性值、下标等来获取特定的节点

路径表达式结果
//title[@lang=“eng”]选择lang属性值为eng的所有title元素
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()>1]选择bookstore下面的book元素,从第二个开始选择
//book/title[text()=‘Harry Potter’]选择所有book下的title元素,仅仅选择文本为Harry Potter的title元素
//book/title[contains(text(), “Harry”)]选择所有book下的文本包含Harry的title元素
/bookstore/book[price>35.00]/title选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

关于xpath的下标:

  • 在xpath中,第一个元素的位置是1
  • 最后一个元素的位置是last()
  • 倒数第二个是last()-1

5.3 谷歌浏览器xpath helper插件的安装和使用

要想利用lxml模块提取数据,需要我们掌握xpath语法规则。接下来我们就来了解一下xpath helper插件,它可以帮助我们练习xpath语法。

xpath helper插件的安装:

1.下载Chrome插件 XPath Helper:

  • 可以在chrome应用商城进行下载,如果无法下载,也可以从下面的链接进行下载
  • 下载地址:https://pan.baidu.com/s/1UM94dcwgus4SgECuoJ-Jcg 密码:337b

2.把文件的后缀名crx改为rar,然后解压到同名文件夹中

3.把解压后的文件夹拖入到已经开启开发者模式的chrome浏览器扩展程序界面

4.重启浏览器后,访问url之后在页面中点击xpath图标,就可以使用了

5.如果是linux或macOS操作系统,无需操作上述的步骤2,直接将crx文件拖入已经开启开发者模式的chrome浏览器扩展程序界面

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

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

相关文章

Linux文件查找之find秘笈

前言Linux的基本特点之一是一切皆文件&#xff0c;在系统管理过程中难免会需要查找特定类型的文件&#xff0c;那么问题来了&#xff1a;如何进行有效且准确的查找呢&#xff1f;本文将对Linux系统中的文件查找工具及用法进行详细讲解。常用工具对比常用的文件查找工具主要有lo…

【机器视觉学习笔记】大津法/Otsu最大类间方差法 最佳阈值处理(C++)

目录概念C源码OtsuThreshold主函数效果完整源码平台&#xff1a;Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文所用源码修改自C opencv 图片二值化最佳阈值确定&#xff08;大津法,OTSU算法)——Sharon Liu 概念 Otsu算法&#xff0c;也叫最大类间方差法&#xff0…

HTML 页面源代码布局介绍

此介绍以google首页源代码截图为例&#xff1a; 从上到下依次介绍&#xff1a; 1.<!DOCTYPE html> 此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范。 XHTML规范&#xff1a;必须小写&#xff0c;有开始结束标签&#xff0c;属性也用双引号。 HTML规范&#xff1a;不…

Python对Protobuf进行序列化与反序列化

Python Protobuf1.了解Protobuf&#xff1a;1.1 Protobuf语法介绍&#xff1a;2. Python使用Protobuf&#xff1a;(windows平台上)1.了解Protobuf&#xff1a; 我们在使用protobuf之前首先要了解protobuf&#xff0c;那么什么是protobuf呢&#xff1f; 官方的解释是&#xff…

sql server management studio 查询的临时文件路径

C:\Users\你的登录名称\Documents\SQL Server Management Studio\Backup FilesC:\Users\你的登录名称\AppData\Local\Temp\sql server management studio 非正常关闭时自动保存的路径在sql server management studio 里创建的“新建查询”且没有手动保存的路径转载于:https://w…

Linux下如何自己编译源代码(制作成可以安装的.deb文件)

以tree实用程序&#xff08;以树型结构获取目录树&#xff09;为例&#xff0c;介绍Ubuntu中如何管理源码包&#xff0c;包括查询&#xff0c;获取&#xff0c;编译源码包&#xff0c;直至安装。1&#xff09; 在获取源码包之前&#xff0c;确保在软件源配置文件/etc/apt/sourc…

K210 / Openmv实现 大津法/Otsu最大类间方差法 自适应二值化

目录源码效果平台&#xff1a;K210 固件版本&#xff1a;maixpy_v0.6.2_54_g897214100_openmv_kmodel_v4_with_ide_support.bin OpenMv库自带Otsu算法: 源码 # Otsu.py - By: Royic - 周三 9月 22 2021import sensor, imagesensor.reset() sensor.set_pixformat(sensor.GRAY…

第一章:OpenCV入门

第一章&#xff1a;OpenCV入门 OpenCV是一个开源的计算机视觉库&#xff0c;1999年有英特尔的Gary Bradski启动。OpenCV库由C和C语言编写&#xff0c;涵盖计算机视觉各个领域内的500多个函数&#xff0c;可以在多个操作系统上运行。它旨在提供一个简洁而又高效的接口&#xff…

神奇的vfork

一段神奇的代码在论坛里看到下面一段代码&#xff1a;int createproc();int main(){pid_t pidcreateproc();printf("%d\n", pid);exit(0);}int createproc(){pid_t pid;if(!(pidvfork())) {printf("child proc:%d\n", pid);return pid;}else return -1;}输…

18、Java并发性和多线程-饥饿与公平

以下内容转自http://ifeve.com/starvation-and-fairness/&#xff1a; 如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间&#xff0c;这种状态被称之为“饥饿”。而该线程被“饥饿致死”正是因为它得不到CPU运行时间的机会。解决饥饿的方案被称之为“公平性”–即…

OpenSceneGraph 3.2 版本修改点

OpenSceneGraph-3.2.0稳定版本发布了&#xff0c;改善了对iOS、Android的支持&#xff0c;支持OpenGL的更多新特性。可以通过 下载版块来进行下载。 OpenSceneGraph 3.2 发布. 版本修改点: 全面对OpenGL ES 1.1 和 2.0 的支持&#xff0c;包括各种扩展。改善QTKit, imageio 以及…

【机器视觉学习笔记】双边滤波算法(C++)

目录源码滤波器主函数效果完整源码平台&#xff1a;Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文所用源码修改自双边滤波(bilateral filter)以及联合双边滤波&#xff08;joint bilateral filter&#xff09;—— flow_specter 源码 滤波器 // 双边滤波 // src…

第二章:图像处理基础

第二章&#xff1a;图像处理基础操作一、图像的基本表示方法&#xff1a;1. 二值图像&#xff1a;2. 灰度图像&#xff1a;3. 彩色图像&#xff1a;二、像素处理&#xff1a;1. 二值图像及灰度图像&#xff1a;2.彩色图像&#xff1a;3. 使用numpy.array访问像素&#xff1a;三…

《Head First设计模式》 读书笔记16 其余的模式(二) 蝇量 解释器 中介者

《Head First设计模式》 读书笔记16 其余的模式&#xff08;二&#xff09; 蝇量 解释器 中介者 蝇量&#xff08;Flyweight Pattern&#xff09; 如想让某个类的一个实例能用来提供许多“虚拟实例”&#xff0c;就使用蝇量模式&#xff08;Flyweight Pattern&#xff09; 。 例…

洛谷P1525 关押罪犯

P1525 关押罪犯 题目描述 S 城现有两座监狱&#xff0c;一共关押着N 名罪犯&#xff0c;编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久&#xff0c;如果客观条件具备则随时可能爆发冲突。我们用“怨气值”&#xff08;一个正整数值&#xff09;来表示…

【机器视觉学习笔记】Hough变换直线检测(C++)

目录源码效果平台&#xff1a;Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文源码摘自OpenCV2马拉松第22圈——Hough变换直线检测原理与实现 源码 #include <opencv2\opencv.hpp> #include <iostream> #include <opencv2\imgproc\types_c.h> #in…

第3章:图像运算

第3章&#xff1a;图像运算one. 图像加法运算&#xff1a;1. 加号运算符"":2. cv2.add()函数&#xff1a;two. 图像加权和&#xff1a;three. 按位逻辑运算&#xff1a;1. 按位与运算&#xff1a;2. 按位或运算&#xff1a;3.按位非运算&#xff1a;4. 按位异或运算&…

分页代码

/// <summary>/// 获得伪静态页码显示链接/// </summary>/// <param name"curPage">当前页数</param>/// <param name"countPage">总页数</param>/// <param name"url">超级链接地址</param>//…

JMS中的消息通信模型

1. MQ简介&#xff1a; 消息队列&#xff08;Message Queue&#xff0c;简称MQ&#xff09;,是应用程序与应用程序之间的一种通信方法。应用程序通过发送和检索出入列队的针对应用程序的数据 - 消息来通信&#xff0c;而无需专用连接来链接它们。程序之间通过在消息中发送数据进…

【机器视觉学习笔记】最近邻插值实现图片任意角度旋转(C++)

目录原理源码RotateImage主函数效果完整源码速度优化源码优化效果平台&#xff1a;Windows 10 20H2 Visual Studio 2015 OpenCV 4.5.3 本文算法改进自图形算法与实战&#xff1a;6.图像运动专题&#xff08;5&#xff09;图像旋转-基于近邻插值的图像旋转 —— 进击的CV 原理…