xpath数据解析方法

10

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

https://mohen.blog.csdn.net/article/details/107311856?spm=1001.2101.3001.6650.2&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2-107311856-blog-122500983.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-2-107311856-blog-122500983.pc_relevant_default&utm_relevant_index=4

(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)