xpath数据解析方法
xpath介绍
简介
xpath是一门在XML和HTML文档中查找信息的语言,可以用来在XML和HTML文档中对元素和属性进行遍历。
安装
pip install lxml
xpath基本语法
①: 安装 lxml 库。
②: from lxml import etree
③: tree= etree.HTML(网页源代码)
④: tree.xpath(一段神奇的符号) # 返回的数据类型是列表,可以通过索引指定获取,或循环取出每个元素!
路径表达式
| 表达式 | 描述 |
| :---: | --- |
| // | 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置。 |
| / | 从根节点选取。选择当前元素的下一级。 |
| @ | 选取属性。 |
| /text | 当前元素的文本内容 |
| [ ]、[@] | 指定元素的索引或者属性特性。 |
| | 表示所有。 |
| @* | 所有属性。 |
常用方法
html = '''
<!-- 第一本书 开始 -->
<book title="西游记" class="box-1 aa bb cc" index="01">
<b class="book-1" href="https://www.###1.com" target="_parent">
<a>《西游记》</a>
</br>
<a href="http://www.baidu.com">百度一下</a>
</b>
<img class="book1-img" id="ps-1" title="图片1" alt="img1.jpg"
src="http://img3m6.ddimg.cn/54/26/28548486-1_b_19.jpg">
<c class="xiaowu laowu">作者:<span>吴承恩</span></c>
<d>今日<span>1000</span>人观看</d>
</book>
<!-- 第一本书 结束 -->
'''
from lxml import etree # 导包
tree = etree.HTML(html) # 实例化html对象
选取节点
// 语法
从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置。
ps = tree.xpath("//a") # 获取所有位置的a标签
pd = tree.xpath("//c//span") # 获取所有位置的c标签中所有位置的span标签
print(ps)
print(pd)
输出为 Element元素对象,选取标签对象中的文本内容和属性在下面【选取文本内容、标签属性】介绍:
# ps返回a的Element元素对象
[<Element a at 0x1f4cc0213c0>, <Element a at 0x1f4cc021580>]
# pd返回span的Element元素对象
[<Element span at 0x1f4cc021600>]
/ 语法
从根节点选取。选择当前元素的下一级。
ps = tree.xpath("//c/span") # 获取所有位置的c标签的下一级span
pd = tree.xpath("//d/span") # 获取所有位置的d标签中下一级的span标签
print(ps)
print(pd)
输出为 Element元素对象,选取标签对象中的文本内容和属性在下面【选取文本内容、标签属性】介绍:
# ps返回所有位置的c标签的下一级span的Element元素对象
[<Element span at 0x24a62d913c0>]
# pd返回所有位置的d标签中下一级的span标签Element元素对象
[<Element span at 0x24a62d91580>]
选取文本内容、标签属性
/text() 语法
选取文本内容:
ps = tree.xpath("//a/text()") # 获取所有位置的a标签中的文本内容
pd = tree.xpath("//c//span/text()")# 获取所有位置的c标签中所有位置的span标签中的文本内容
print(ps)
print(pd)
输出 指定标签的文本内容
# ps输出所有位置的a标签中的文本内容
['《西游记》', '百度一下']
# pd输出所有位置的c标签中所有位置的span标签中的文本内容
['吴承恩']
@ 语法
获取标签属性:
ps = tree.xpath("//a/@href") # 获取所有位置的a标签中的href属性值
pd = tree.xpath("//book/img/@src")# 获取所有位置的book标签中所有位置的img标签中的src属性值
print(ps)
print(pd)
输出 标签的属性值
# ps 输出所有位置的a标签中的href属性值
['http://www.baidu.com']
# pd 输出所有位置的book标签中所有位置的img标签中的src属性值
['http://img3m6.ddimg.cn/54/26/28548486-1_b_19.jpg']
[ ] 、[@ ] 语法
[@] 指定属性的标签:
# 获取所有位置class属性值为box-1 aa bb cc的book标签
ps = tree.xpath("//book[@class='box-1 aa bb cc']")
# 获取所有位置class属性值为box-1 aa bb cc的book标签下所有位置id属性值为ps-1的img标签
pd = tree.xpath("//book[@class='box-1 aa bb cc']//img[@id='ps-1']")
print(ps)
print(pd)
输出 指定属性的标签对象
# ps 输出所有位置class属性值为box-1 aa bb cc的book标签对象
[<Element book at 0x21af3da1280>]
# pd 输出获取所有位置class属性值为box-1 aa bb cc的book标签下所有位置id属性值为ps-1的img标签对象
[<Element img at 0x21af3da10c0>]
[ ] 指定索引
# 获取所有位置book标签下所有位置的a标签的第一个标签的文本内容
ps = tree.xpath("//book//a[1]/text()")
# 获取所有位置book标签下所有位置的span标签的第二个标签的文本内容
pd = tree.xpath("//book//a[2]/text()")
print(ps)
print(pd)
输出 指定位置序号的标签:
# ps输出所有位置book标签下所有位置的a标签的第一个标签的文本内容
['《西游记》']
# pd输出所有位置book标签下所有位置的a标签的第一个标签的文本内容
['百度一下']
、@ 语法
表示所有 @所有属性
# 获取所有位置book标签的所有属性值
ps = tree.xpath("//book/@*")
# 获取所有位置c标签下所有标签的文本
pd = tree.xpath("//c/*/text()")
# 获取所有位置book标签下所有位置的不指定属性的img标签的src值
po = tree.xpath("//book//img[@*]/@src")
print(ps)
print(pd)
print(po)
输出:
# ps 输出所有位置book标签的所有属性值
['西游记', 'box-1 aa bb cc', '01']
# pd 输出所有位置c标签下所有标签的文本
['吴承恩']
# po 输出所有位置book标签下所有位置的不指定属性的img标签的src值
['http://img3m6.ddimg.cn/54/26/28548486-1_b_19.jpg']
其他方法
使用函数
contains
有的时候,class作为选择条件的时候不合适@class='....' 这个是完全匹配,当网页样式发生变化时,class或许会增加或减少像属性会变化的class。用contains就能很方便 。
# 迷糊匹配: 所有标签中 class属性值 包含关键字'xiao'的标签,下一级的span标签文本内容
code_data =tree.xpath('//*[contains(@class,"xiao")]/span/text()')
print(code_data)
# 迷糊匹配: 所有标签 文本内容 包含关键字'《' 的标签文本内容
code_data1 =tree.xpath('//*[contains(text(),"《")]/text()')
print(code_data1)
输出
# code_data 输出
['吴承恩']
# code_data1输出
['《西游记》']
其他函数
【更多 函数的使用参考下面==> xpath参考文档(3)】
xpath参考文档
技术参考文档:
(1)Python爬虫之xpath
(2)Python中xpath解析
https://blog.csdn.net/qq_62789540/article/details/122500983
(3)python使用xpath(超详细)
https://www.cnblogs.com/mxjhaima/p/13775844.html
xpath案例应用
xpath解析四大名著数据
实现思路:
自定义了一个网页html字符串数据(模拟网络请求获取的html数据),通过etree.HTML(html)实例化xpath对象,根据需求综合使用上述讲解的语法筛选出相应的数据。
案例【xpath解析四大名著数据】代码如下:
html = '''
<div class="BOX">
<!-- 内容模块 开始 -->
<div class="App max-box" index="0" style="max-width: 868px;min-width: 599px; height:360px;margin: 0 auto;">
<!-- 第一本书 开始 -->
<book title="西游记" class="box-1 aa bb cc" index="01">
<b class="book-1" href="https://www.###1.com" target="_parent">
<a>《西游记》</a>
</br>
<a href="http://www.baidu.com">百度一下</a>
</b>
<img class="book1-img" id="ps-1" title="图片1" alt="img1.jpg"
src="http://img3m6.ddimg.cn/54/26/28548486-1_b_19.jpg">
<c class="xiaowu laowu">作者:<span>吴承恩</span></c>
<d>今日<span>1000</span>人观看</d>
</book>
<!-- 第一本书 结束 -->
<!-- 第二本书 开始 -->
<book title="三国演义" class="box-2 aa bb cc" index="02">
<b class="book-2" href="https://www.###2.com" target="_parent">
<a>《三国演义》</a>
</br>
<a href="http://www.baidu.com">百度一下</a>
</b>
<img class="book2-img" id="ps-2" title="图片2" alt="img2.jpg"
src="http://img3m9.ddimg.cn/2/7/28514279-1_b_17.jpg">
<c class="xiaoluo laowu">作者:<span>罗贯中</span></c>
<d>今日<span>2000</span>人观看</d>
</book>
<!-- 第二本书 结束 -->
<!-- 第三本书 开始 -->
<book title="水浒传" class="box-3 aa bb cc" index="03">
<b class="book-3" href="https://www.###3.com" target="_parent">
<a>《水浒传》</a>
</br>
<a href="http://www.baidu.com">百度一下</a>
</b>
<img class="book3-img" id="ps-3" title="图片3" alt="img3.jpg"
src="http://img3m5.ddimg.cn/24/28/29162355-1_b_2.jpg">
<c class="xiaoshi laowu">作者:<span>施耐庵</span></c>
<d>今日<span>3000</span>人观看</d>
</book>
<!-- 第三本书 结束 -->
<!-- 第四本书 开始 -->
<book title="红楼梦" class="box-4 aa bb cc" index="04">
<b class="book-4" href="https://www.###4.com" target="_parent">
<a>《红楼梦》</a>
</br>
<a href="http://www.baidu.com">百度一下</a>
</b>
<img class="book4-img" id="ps-4" title="图片4" alt="img4.jpg"
src="http://img3m4.ddimg.cn/91/30/29249344-1_b_9.jpg">
<c class="xiaocao laowu">作者:<span>曹雪芹</span></c>
<d>今日<span>4000</span>人观看</d>
</book>
<!-- 第一本书 结束 -->
</div>
<!-- 内容模块 结束 -->
</div>
'''
from lxml import etree
tree = etree.HTML(html)
'''age:'''
# index:01
index = tree.xpath('//book/@index')
print(index)
# name: 西游记
name = tree.xpath('//book//b/a[1]/text()')
print(name)
# code: 吴承恩
code = tree.xpath('//c[@*]/span/text()')
print(code)
# url: https://www.###.com
url = tree.xpath('//div[@class="App max-box"][1]/book/b/@href')
print(url)
# img_code: 图片1
img_code = tree.xpath('//book/img/@title')
print(img_code)
# img_url: http://img3m6.ddimg.cn/54/26/28548486-1_b_19.jpg
img_url = tree.xpath('//book/img/@src')
print(img_url)
# age: 今日观看人数
age = tree.xpath('//d/span/text()')
print(age)
# 整理数据
data = []
dict ={}
for i in range(len(index)):
dict['index']= index[i]
dict['name'] = name[i]
dict['code'] = code[i]
dict['url'] = url[i]
dict['img_code'] = img_code[i]
dict['img_url'] = img_url[i]
dict['age'] = age[i]
data.append(dict)
print(data)