10.爬虫---XPath插件安装并解析爬取数据

10.XPath插件安装并解析爬取数据

    • 1.XPath简介
    • [2.XPath helper安装](#2.XPath helper安装)
    • [3.XPath 常用规则](#3.XPath 常用规则)
    • 4.实例引入
      • [4.1 `//`匹配`所有节点`](#4.1 //匹配所有节点)
      • [4.2 `/` 或 `//` 匹配`子节点`或`子孙节点`](#4.2 /// 匹配子节点子孙节点)
      • [4.3 `..`或 `parent::`匹配`父节点`](#4.3 ..parent::匹配父节点)
      • [4.4 `@`匹配`属性`](#4.4 @匹配属性)
      • [4.5 `text()`文本获取](#4.5 text()文本获取)
      • [4.6 `@`属性获取](#4.6 @属性获取)
      • [4.7 属性多值匹配](#4.7 属性多值匹配)

1.XPath简介

XPath是一门在XML文档中查找信息的语言,它使用路径表达式来选取XML文档中的节点或者节点集。XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力,允许开发者精确地定位XML文档中的元素、属性或节点集。

2.XPath helper安装

XPath Helper是一款专用于chrome内核浏览器的实用型爬虫网页解析工具

下载后得到了后缀.crx 的一个文件,然后打开谷歌浏览器的设置--->拓展程序--->管理拓展程序

XPath_Helper2.0.2.crx文件鼠标左键 拖入拓展程序界面,然后添加拓展程序

XPath_Helper 就安装好了

XPath_Helper固定为快捷方式

3.XPath 常用规则

表 达 式 描  述
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
.. 选取当前节点的父节点
@ 选取属性
[] 表示谓词,用于筛选符合条件的节点

4.实例引入



复制后的XPath如下:

bash 复制代码
//*[@id="content"]/div/div[1]/div/div/table[1]/tbody/tr

把复制的XPath 粘贴到 XPath_Helper

上面的 xpath语法只匹配了一项这样的数据,接下来我们来匹配多项这样的数据,把角标去了得到下面匹配多项的语法

bash 复制代码
//*[@id="content"]/div/div/div/div/table/tbody/tr


这样就匹配到了多项这样的数据

我们用这部分代码来分析:

html 复制代码
<tr class="item">
    <td width="100" valign="top">
        <a class="nbg" href="https://movie.douban.com/subject/34971728/" title="盟军敢死队">
            <img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2908456064.webp" width="75" alt="盟军敢死队" class="">
        </a>
    </td>
    <td valign="top">
        <div class="pl2">
            <a href="https://movie.douban.com/subject/34971728/" class="">
                盟军敢死队
                / <span style="font-size:13px;" class="">绝密型战 / 无限制军团(港)</span>
            </a>
            <p class="pl">2024-04-18(中国香港) / 2024-04-19(美国) / 2024-05-24(中国大陆) / 亨利·卡维尔 / 艾莎·冈萨雷斯 / 阿兰·里奇森 / 亚历克斯·帕蒂弗 / 赫洛·费因斯-提芬 / 巴布斯·奥卢桑莫昆 / 亨利·扎格 / 蒂尔·施威格 / 亨利·戈尔丁 / 加利·艾尔维斯 / 弗莱迪·福克斯...</p>
            <div class="star clearfix">
                <span class="allstar35"></span>
                <span class="rating_nums">7.1</span>
                <span class="pl">(20708人评价)</span>
            </div>
        </div>
    </td>
</tr>

使用之前,首先要确保安装好 lxml 库。如尚未安装,可以使用 pip3 来安装:

bash 复制代码
pip3 install lxml
py 复制代码
from lxml import etree
text = '''
<tr class="item">
    <td width="100" valign="top">
        <a class="nbg" href="https://movie.douban.com/subject/34971728/" title="盟军敢死队">
            <img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2908456064.webp" width="75" alt="盟军敢死队" class="">
        </a>
    </td>
    <td valign="top">
        <div class="pl2">
            <a href="https://movie.douban.com/subject/34971728/" class="">
                盟军敢死队
                / <span style="font-size:13px;" class="">绝密型战 / 无限制军团(港)</span>
            </a>
            <p class="pl">2024-04-18(中国香港) / 2024-04-19(美国) / 2024-05-24(中国大陆) / 亨利·卡维尔 / 艾莎·冈萨雷斯 / 阿兰·里奇森 / 亚历克斯·帕蒂弗 / 赫洛·费因斯-提芬 / 巴布斯·奥卢桑莫昆 / 亨利·扎格 / 蒂尔·施威格 / 亨利·戈尔丁 / 加利·艾尔维斯 / 弗莱迪·福克斯...</p>
            <div class="star clearfix">
                <span class="allstar35"></span>
                <span class="rating_nums">7.1</span>
                <span class="pl">(20708人评价)</span>
            </div>
        </div>
    </td>
</tr>
'''
#方法一: 读取text 文本
html = etree.HTML(text) 
#方法二: 读取html文件
# html = etree.parse('./test.html', etree.HTMLParser())
result = etree.tostring(html)
print(result.decode('utf-8'))
  • etree.HTML(text) 方法一: 读取text 文本
  • etree.parse('./test.html', etree.HTMLParser()) 法二: 读取html文件

经过这两种方法处理之后,节点标签被补全,并且还自动添加了 body、html 节点
结果:

好家伙,unicode 编码,还需要再转一次 unicode 转中文,用 html 模块下的 unescape 方法
修改后的代码:

py 复制代码
from lxml import etree
import html
text = '''
<tr class="item">
    <td width="100" valign="top">
        <a class="nbg" href="https://movie.douban.com/subject/34971728/" title="盟军敢死队">
            <img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2908456064.webp" width="75" alt="盟军敢死队" class="">
        </a>
    </td>
    <td valign="top">
        <div class="pl2">
            <a href="https://movie.douban.com/subject/34971728/" class="">
                盟军敢死队
                / <span style="font-size:13px;" class="">绝密型战 / 无限制军团(港)</span>
            </a>
            <p class="pl">2024-04-18(中国香港) / 2024-04-19(美国) / 2024-05-24(中国大陆) / 亨利·卡维尔 / 艾莎·冈萨雷斯 / 阿兰·里奇森 / 亚历克斯·帕蒂弗 / 赫洛·费因斯-提芬 / 巴布斯·奥卢桑莫昆 / 亨利·扎格 / 蒂尔·施威格 / 亨利·戈尔丁 / 加利·艾尔维斯 / 弗莱迪·福克斯...</p>
            <div class="star clearfix">
                <span class="allstar35"></span>
                <span class="rating_nums">7.1</span>
                <span class="pl">(20708人评价)</span>
            </div>
        </div>
    </td>
</tr>
'''
htmls = etree.HTML(text)
result = etree.tostring(htmls).decode('utf-8')
print(html.unescape(result))

修改后的结果:

4.1 //匹配所有节点

py 复制代码
html = etree.HTML(text)
result = html.xpath('//*')
print(result)

运行结果:

py 复制代码
[<Element html at 0x14cfea8ef80>, <Element body at 0x14c8bdf7540>, <Element tr at 0x14c8be450c0>, <Element td at 0x14c8be44fc0>, <Element a at 0x14c8be45100>, <Element img at 0x14c8be451c0>, <Element td at 0x14c8be45340>, <Element div at 0x14c8be45440>, <Element a at 0x14c8be45400>, <Element span at 0x14c8be45180>, <Element p at 0x14c8be452c0>, <Element div at 0x14c8be45500>, <Element span at 0x14c8be45540>, <Element span at 0x14c8be45580>, <Element span at 0x14c8be455c0>]

这里使用 * 代表匹配所有节点,也就是整个 HTML 文本中的所有节点都会被获取。可以看到,返回形式是一个列表,每个元素是 Element 类型,其后跟了节点的名称,如 html、body、div、ul、li、a 等,所有节点都包含在列表中了

如果想获取所有 <span> 节点,示例如下:

py 复制代码
html = etree.HTML(text)
result = html.xpath('//span')
print(result)

运行结果:

bash 复制代码
[<Element span at 0x29a110e7540>, <Element span at 0x29a111450c0>, <Element span at 0x29a11144fc0>, <Element span at 0x29a11145100>]

4.2 /// 匹配子节点子孙节点

  • 获取<td> 下的直接子节点
bash 复制代码
html = etree.HTML(text)
result = html.xpath('//td/a')
print(result)

结果:

bash 复制代码
[<Element a at 0x2522492f540>]
  • 获取<td> 下的子孙节点
bash 复制代码
html = etree.HTML(text)
result = html.xpath('//td//a')
print(result)

结果:

bash 复制代码
[<Element a at 0x21f6c4d7540>, <Element a at 0x21f6c535040>]

这里我们要注意 / 和 // 的区别,其中 / 用于获取直接子节点,// 用于获取子孙节点。

4.3 ..parent::匹配父节点

现在首先选中 width 属性为 100 的 td 节点,然后获取其父节点,再获取其 class 属性,相关代码如下:

py 复制代码
html = etree.HTML(text)
result = html.xpath('//td[@width="100"]/../@class')
print(result)
py 复制代码
html = etree.HTML(text)
result = html.xpath('//td[@width="100"]/parent::*/@class')
print(result)

结果:

bash 复制代码
['item']

4.4 @匹配属性

选取 class 为 rating_nums 的 span 节点,可以这样实现:

py 复制代码
html = etree.HTML(text)
result = html.xpath('//span[@class="rating_nums"]')
print(result)

结果:

py 复制代码
[<Element span at 0x280c13a8b80>]

4.5 text()文本获取

text 方法获取节点中的文本,接下来尝试获取前面 p 节点中的文本

py 复制代码
html = etree.HTML(text)
result = html.xpath('//p[@class="pl"]/text()')
print(result)

结果:

bash 复制代码
['2024-04-18(中国香港) / 2024-04-19(美国) / 2024-05-24(中国大陆) / 亨利·卡维尔 / 艾莎·冈萨雷斯 / 阿兰·里奇森 / 亚历克斯·帕蒂弗 / 赫洛·费因斯-提芬 / 巴布斯·奥卢桑莫昆 / 亨利·扎格 / 蒂尔·施威格 / 亨利·戈尔丁 / 加利·艾尔维斯 / 弗莱迪·福克斯...']

4.6 @属性获取

我们知道用 text 方法可以获取节点内部文本,那么节点属性该怎样获取呢?其实还是用 @ 符号就可以。例如,我们想获取所有 a 节点的 href 属性,代码如下:

py 复制代码
html = etree.HTML(text)
result = html.xpath('//a/@href')
print(result)

结果:

bash 复制代码
['https://movie.douban.com/subject/34971728/', 'https://movie.douban.com/subject/34971728/']

4.7 属性多值匹配

有时候,某些节点的某个属性可能有多个值,例如:

py 复制代码
html = etree.HTML(text)
result = html.xpath('//div[@class="star"]')
print(result)

这里 HTML 文本中 div 节点的 class 属性有两个值 star 和 clearfix,此时如果还想用之前的属性匹配获取,就无法匹配了,此时的运行结果如下:

bash 复制代码
[]

这时就需要用 contains 方法了,代码可以改写如下:

py 复制代码
html = etree.HTML(text)
result = html.xpath('//div[contains(@class, "star")]')
print(result)

这样通过 contains 方法,给其第一个参数传入属性名称,第二个参数传入属性值,只要此属性包含所传入的属性值,就可以完成匹配了

此时运行结果如下:

py 复制代码
[<Element div at 0x1f696514e80>]

其他一些高级用法可参考

1.w3school: http://www.w3school.com.cn/xpath/xpath_axes.asp

2.Python爬虫杂记 - Xpath高级用法:https://www.jianshu.com/p/4fef4142b33f

相关推荐
亿牛云爬虫专家1 小时前
捕获抖音截图:如何用Puppeteer保存页面状态
爬虫·爬虫代理·puppeteer·抖音·亿牛云·代理ip·douyin
亿牛云爬虫专家1 小时前
Puppeteer教程:使用CSS选择器点击和爬取动态数据
javascript·css·爬虫·爬虫代理·puppeteer·代理ip
abments3 小时前
JavaScript逆向爬虫教程-------基础篇之常用的编码与加密介绍(python和js实现)
javascript·爬虫·python
小白学大数据9 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
数据小小爬虫10 小时前
如何用Java爬虫“偷窥”淘宝商品类目API的返回值
java·爬虫·php
B站计算机毕业设计超人15 小时前
计算机毕业设计Python+大模型农产品价格预测 ARIMA自回归模型 农产品可视化 农产品爬虫 机器学习 深度学习 大数据毕业设计 Django Flask
大数据·爬虫·python·深度学习·机器学习·课程设计·数据可视化
single_ffish16 小时前
XPath:网络爬虫中的数据提取利器
爬虫·python
abments18 小时前
JavaScript逆向爬虫教程-------基础篇之JavaScript密码学以及CryptoJS各种常用算法的实现
javascript·爬虫·密码学
小爬虫程序猿19 小时前
python爬虫获得淘宝商品类目 API 返回值说明
开发语言·爬虫·python
week_泽20 小时前
python爬虫(二)爬取国家博物馆的信息
开发语言·爬虫·python