Python XPath 和 lxml
XPath 和 lxml
XPath 全称为 Xml Path Language,即 Xml 路径语言,是一种在 Xml 文档中查找信息的语言。它提供了非常简洁的路径选择表达式,几乎所有的节点定位都可以用它来选择。
XPath 可以用于 Xml 和 Html,在爬虫中经常使用 XPath 获取 Html 文档内容。
lxml 是 Python 语言用 Xpath 解析 XML、Html文档功能最丰富的、最容易的功能模块。
XPath 术语
节点
在 XPath 中有七种节点分别是元素、属性、文本、文档、命名空间、处理指令、注释,前3种节点为常用节点
请看下面的 Html 例子,(注:这个例子全文都需要使用)
<!DOCTYPE html>
<html>
<body>
<div>
<!-- 这里是注释 -->
<h4>手机品牌商<span style="margin-left:10px">4</span></h4>
<ul>
<li>小米</li>
<li>华为</li>
<li class='blank'> OPPO </li>
<li>苹果</li>
</ul>
</div>
<div>
<h4>电脑品牌商<span style="margin-left:10px">3</span></h4>
<ul class="ul" style="color:red">
<li>戴尔</li>
<li>机械革命</li>
<li>ThinkPad</li>
</ul>
</div>
</body>
</html>
在上面的例子中
<html> 为文档节点
<li>小米</li> 为元素节点
class='blank' 为属性节点
<!-- 这里是注释 --> 为注释节点
节点关系
在 XPath中有多中节点关系分别是父节点、子节点、同胞节点、先辈节点、后代节点
在上面的例子中
父节点:每个元素以及属性都有一个父节点,如:div 节点的父节点是 body 节点
子节点:元素节点可有零个、一个或多个子节点,如:第一个 ul 节点的子节点是4个 li 节点
同胞节点:拥有相同的父节点的节点,如:两个 div 节点是同胞节点
先辈节点:某节点的父节点、父节点的父节点...,如:ul 节点的先辈节点有 div 节点、body 节点
后代节点:某个节点的子节点,子节点的子节点...,如:body 节点的后代节点有div 节点、ul 节点、li 节点
XPath 语法
基本语法
表达式 | 描述 |
---|---|
nodeName | 选择nodeName节点的所有子节点 |
/ | 从根节点开始 |
// | 从匹配的节点开始选择节点 |
. | 选择当前节点 |
.. | 选择当前节点的父节点 |
@ | 选择元素 |
* | 匹配任意元素节点 |
@* | 匹配任意属性节点 |
用上面的 Html 文档举个例子
路径表达式 | 描述 |
---|---|
body | 选取 body 的所有子节点 |
/html | 选取 html 节点 |
//div | 选取所有 div 节点 |
//div/./h4 | div 节点下的 h4 节点 |
../div | 选取当前节点的父节点下的所有 div 节点 |
//@class | 所有带有 class 元素的节点 |
//* | 选择所有节点 |
//@* | 选择所有属性节点 |
常用函数
表达式 | 描述 |
---|---|
position() | 返回节点的 index 位置 |
last() | 返回节点的个数 |
contains(string1,string2) | string1 是否包含 string2 |
text() | 返回文本节点 |
comment() | 返回注释节点 |
normalize-space(string) | 去除首位空格,中间多个空格用一个空格代替 |
substring(string,start,len) | 返回从 start 位置开始的指定长度的子字符串,第一个字符下标为1 |
substring-before(string1,string2) | 返回string1中位于第一个string2之前的部分 |
substring-after(string1,string2) | 返回string1中位于第一个string2之后的部分 |
同样用上面的Html文档举个例子
路径表达式 | 描述 |
---|---|
//div[position()>1] | 选择第二个 div 节点 |
//div[last()] | 选择最后一个 div 节点 |
contains(//h4[2],'手机') | 第二个 h4 标签是否包含手机字符串 |
//li/text() | li 节点中的文本内容 |
//div/comment() | div 节点下的 html 注释 |
normalize-space(//li[@class='blank']) | li 节点下 class属性为 blank 的文本去掉空格 |
substring(//h4[1],1,2) | 第一个 h4 节点的前2个字 |
substring-before(//h4[1],'品牌商') | 第一个 h4 节点的品牌商字符串之前的字符串 |
substring-after(//h4[1],'品牌商') | 第一个 h4 节点的品牌商字符串之后的字符串 |
谓语
XPath 中的谓语就是删选表达式,相当于 SQL 中的 Where 条件,谓语被嵌在 [ ] 中
路径表达式 | 描述 |
---|---|
//div[1] | 选择第一个 div 节点 |
//div[2]/ul/li[last()] | 选择第二个 div 节点下的最后一个 li 节点 |
//div[2]/ul/li[position()>3] | 选择第二个 div 节点下的前两个 li 节点 |
//ul[@class] | 选择所有带 class 属性的 ul 节点 |
//ul[@class='computer'] | 选择 class 属性为 computer 的 ul 节点 |
//h4[span = 4] | 选择 h4 节点下 span 值等于4的节点 |
Xpath 结语
以上内容介绍了 XPath 的基本语法,下面将介绍 XPath 如何在 Python 中使用。
lxml 模块
安装
sudo pip3 install lxml==4.4.1
解析 HTML 文档
lxml.etree 一个强大的 Xml 处理模块,etree 中的 ElementTree 类是一个主要的类,用于对XPath的解析、增加、删除和修改节点。
from lxml import etree
etree.parse() 函数可以解析一个网页文件还可以解析字符串, 在网页中下载的数据一般都是字符串形式的,使用 parse(StringIO(str)) 将整个页面内容解析加载构建一个 ElementTree 对象,ElementTree 可以使用 XPath 语法精准找到需要的数据。
1.加载页面到内存
from lxml import etree
from io import StringIO
test_html = '''
<html>
<body>
<div>
<!-- 这里是注释 -->
<h4>手机品牌商<span style="margin-left:10px">4</span></h4>
<ul>
<li>小米</li>
<li>华为</li>
<li class='blank'> OPPO </li>
<li>苹果</li>
</ul>
</div>
<div>
<h4>电脑品牌商<span style="margin-left:10px">3</span></h4>
<ul class="ul" style="color:red">
<li>戴尔</li>
<li>机械革命</li>
<li>ThinkPad</li>
</ul>
</div>
</body>
</html>'''
html = etree.parse(StringIO(test_html))
print(html)
结果:
<lxml.etree._ElementTree object at 0x10bd6b948>
2.获取所有 li 标签数据
li_list = html.xpath('//li')
print("类型:")
print(type(li_list))
print("值:")
print(li_list)
print("个数:")
print(len(li_list))
for l in li_list:
print("li文本为:" + l.text)
结果:
类型:
<class 'list'>
值:
[<Element li at 0x10543c9c8>, <Element li at 0x10543ca08>, <Element li at 0x10543ca48>, <Element li at 0x10543ca88>, <Element li at 0x10543cac8>, <Element li at 0x10543cb48>, <Element li at 0x10543cb88>]
个数:
7
li文本为:小米
li文本为:华为
li文本为:OPPO
li文本为:苹果
li文本为:戴尔
li文本为:机械革命
li文本为:ThinkPad
3.获取带 class='blank' 属性数据
blank_li_list = html.xpath('//li[@class="blank"]')
print("类型:")
print(type(blank_li_list))
print("值:")
print(blank_li_list)
print("个数:")
print(len(blank_li_list))
for l in blank_li_list:
print("li文本为:" + l.text)
结果:
类型:
<class 'list'>
值:
[<Element li at 0x105253a48>]
个数:
1
li文本为:OPPO
4.属性操作
ul = html.xpath('//ul')[1]
#遍历属性
for name, value in ul.attrib.items():
print('{0}="{1}"'.format(name, value))
#添加新的属性
ul.set("new_attr", "true")
# 获取单个属性
new_attr = ul.get('new_attr')
print(new_attr)
结果:
class="ul"
style="color:red"
true
5.获取最后一个div标签数据
last_div = html.xpath('//div[last()]')
print("TAG:")
print(last_div.tag)
print("值:")
print(last_div.text)
结果
div
值:
6.添加子节点
child = etree.Element("child")
child.text = "这里是新的子元素"
last_div.append(child)
# 在最后一个 div 标签查找新的子元素
clild_text = last_div.find("child").text
print(clild_text)
7.删除子元素
# 查找并设置第一个查询到的元素
first_ul = html.find("//ul")
ul_li = first_ul.xpath("li")
for li in ul_li:
# 删除元素
first_ul.remove(li)
ul_li = first_ul.xpath("li")
if len(ul_li) == 0:
print("元素被删除了")
8.遍历元素后代
body = html.find("body")
for sub in body.iter():
print(sub.tag)
print(sub.text)
结果
body
div
<cyfunction Comment at 0x10c374b10>
这里是注释
h4
手机品牌商
span
4
ul
...
工具
在 google 浏览器开发者模式下,Elements 界面选择元素后右键 Copy,可以 Copy 元素的 XPath 路径
XPath Helper 是一个 google 浏览器插件,可以验证 XPath 是否正确
总结
学习了 XPAth 的知识,可以快速匹配单个或多个元素节点和属性,在工作中大大加快了工作的效率。
lxml 是一个 Python 中强大的 Xml 和 Html 处理模块,结合 XPath 的使用在程序中快速、便捷的分析、修改网页内容。
Python XPath 和 lxml相关推荐
- Python:XPath与lxml类库
什么是XML XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 的设计宗旨是传输数据,而非显示数据 XML 的标签需要 ...
- 【Python爬虫学习笔记4】结合Xpath与lxml库解析数据
在之前的学习中了解了如何使用爬虫向目标服务器发送请求并获取响应,而此后便是要对响应进行处理,这里的处理在爬虫中通常指的是数据解析,即将相应内容数据化以方便我们进行有效数据的提取.在此过程中,有许多解析 ...
- 【Python】数据提取xpath和lxml模块(豆瓣电影排行榜的爬虫)
xpath xpath:一门从html中提取数据的语言 xpath语法 1.选择节点(标签) /html/head/meta :能够选中html下的head下的所有的meta标签 2.// :能 ...
- python——xpath
python--xpath 1.xpath简介 2. 安装 3. 数据转换 4. 调用xpath方法 1.xpath简介 xpath是语法不是解析库 xpath语法: 内容 语法 节点 / 跨节点 / ...
- Python数据提取-lxml模块
更多python教程请到友情连接: 菜鸟教程https://www.piaodoo.com 初中毕业读什么技校 http://cntkd.net 茂名一技http://www.enechn.com p ...
- python lxml安装失败,Python pip安装lxml出错的问题解决办法
Python pip安装lxml出错的问题解决办法 1. 在使用pip安装lxml过程中出现了一下错误: >>> pip install lxml C:\Users\Chen&g ...
- python xpath介绍和新闻内容爬虫
二十.python xpath介绍和新闻内容爬虫 Xpath介绍 用xpath提取感兴趣的内容 一个网页文档是一个半结构化的数据,其实html文档就是一个树形结构.根节点是html 用正则表达式也可以 ...
- python xpath爬取豆瓣图书Top 250存入csv文件并解决csv乱码问题
我上次分享过关于爬取豆瓣电影top250的实战:BeautifulSoup爬取豆瓣电影top250信息 和 python BeautifulSoup爬取豆瓣电影top250信息并写入Excel表格 , ...
- 使用Python+xpath爬取知网所有中英文期刊的封面背景图片
使用Python+xpath+beautifulsoup爬取知网所有中英文期刊的封面背景图片` import json import requests from bs4 import Beautifu ...
最新文章
- 学习valueOf和toString,理解隐式转化规则
- tomcat:Could not publish to the server. java.lang.IndexOutOfBoundsException
- Polycarp Recovers the Permutation 构造(1000)
- 我终于拿到CMU的offer了!
- matlab ip 大端,MATLAB格式化输出控制
- sklearn库各个算法学习笔记
- python枚举函数_python dict函数枚举对象
- 数据库系统的并发控制的两种实现模型
- Markdown安装,破解,修改中文
- c语言实验报告字符数组,C语言实验报告《数组》
- 方波通过RC滤波器波形-Matlab仿真
- JeecgBoot商业版源码下载
- ZoomIt使用方法
- Unix与Linux、Minx、Minix
- sql语句查询一天24小时每个小时数据,查询时间段内每天数据
- 12.7亿入股五星电器背后,京东家电想成为线上线下“王者”
- Linux-菜鸟入门自学 (二)
- 物联网(IOT) 数据库需求和当前技术解析
- 计算机安装硬盘后无法启动不了,双硬盘无法启动提示"invalid partition table"开不了机怎么解决?...
- 定义域计算机,函数的定义域和值域