Python爬虫学习之数据提取(XPath)

2023-11-20

概述

XPath的全称是XML Path Language, 即XML路径语言,用来在XML文档中查找信息。虽然最初是用来搜寻XML文档的,但是同样适用于HTML文档的搜索。

常用规则

表达式 描述
nodename 选取此节点的所有子节点
/ 从当前节点选取直接子节点
// 从当前节点选取子孙节点
. 选取当前节点
. . 选取当前节点的父节点
@ 选取属性

运算符及介绍

运算符 描述 实例 返回值
or num=1 or num=2 如果num值为1或者2,返回true,如果为3,则返回false
and num> 1 and num<3 如果num等于2,返回true,否则返回false
mod 计算除法余数 3 mod 2 1
| 计算两个节点集 //num1|//num2 返回所有拥有num1与num2元素的节点
+ 加法 1+1 2
- 减法 2-1 1
* 乘法 2*3 6
div 除法 8 div 4 2
= 等于 num=5 如果num是5,返回true,否则返回false
!= 不等于 num!=5 如果num是6,返回true,如果num是5则返回false
< 小于 num<5 如果num是3,返回true,如果num是7则返回false
<= 小于等于 num<=5 如果num是5,返回true,如果num是6则返回false
> 大于 num>5 如果num是8,返回true,如果num是3则返回false
>= 大于等于 num>=5 如果num是5,返回true,如果num是3则返回false

准备工作

使用XPath对HTML解析,需要安装Python的lxml库。安装命令如下:

# pip 命令
pip install lxml

# pip3 命令
pip3 install lxml

# conda 命令
conda install lxml

实例

目标网站 http://www.biqugei.net/ , 首先抓取网站首页内容

import requests

res = requests.get("http://www.biqugei.net/")

print(res.text)
# 以下只展示本周热读推荐部分结果

<div class="tMEWK container body-content">
	<div class="enW3B panel panel-default">
		<div class="5232g panel-heading">
			<span class="3bNs6 glyphicon glyphicon-fire" aria-hidden="true"></span> 本周热读推荐<a class="6B69i pull-right" href="/top.html">More+</a>
		</div>
		<div class="5chMn panel-body">
			<div class="Zi0mT row">
			    							<div class="elytd col-xs-4 book-coverlist">
					<div class="9XaRE row">
						<div class="7ukSL col-sm-5">
							<a href="/page/detail65541.html" class="vqocg thumbnail" style="background-image:url(https://img.picturecdn.com/files/article/image/65/65536/65536s.jpg)"></a>
						</div>
						<div class="HFrEh col-sm-7 pl0">
							<div class="RAgOj caption">
								<h4 class="sYdCt fs-16 text-muted"><a href="/page/detail65541.html" title="皇家的和尚">皇家的和尚</a></h4>
								<small class="rI9eW fs-14 text-muted">蓅謃</small>
								<p class="UxRCn fs-12 text-justify hidden-xs">冯小宝穿越了,竟然变成了名副其实的花和尚。别人穿越都是带着王霸之气,他却只想如何活下去!大唐高宗年间,那是一个多姿多彩的时代,既有威震天下的名臣武将,李靖,..</p>
							</div>
						</div>
					</div>
				</div>
											<div class="PIM0V col-xs-4 book-coverlist">
					<div class="T3nv6 row">
						<div class="hG1m3 col-sm-5">
							<a href="/page/detail1038.html" class="2JGuv thumbnail" style="background-image:url(https://img.picturecdn.com/files/article/image/1/1033/1033s.jpg)"></a>
						</div>
						<div class="IB1G8 col-sm-7 pl0">
							<div class="Bf5Dy caption">
								<h4 class="M8e22 fs-16 text-muted"><a href="/page/detail1038.html" title="此情惟你独钟">此情惟你独钟</a></h4>
								<small class="Ekvg8 fs-14 text-muted">阮白</small>
								<p class="q87XX fs-12 text-justify hidden-xs">定好的试管婴儿,突然变成了要跟那个男人同床怀孕,一夜缠绵,她被折磨的浑身瘫软!慕少凌,慕家高高在上的继承人,沉稳矜贵,冷厉霸道,这世上的事,只有他不想办的,..</p>
							</div>
						</div>
					</div>
				</div>
											<div class="im7CT col-xs-4 book-coverlist">
					<div class="y7Rws row">
						<div class="9wTjx col-sm-5">
							<a href="/page/detail1292.html" class="faVGI thumbnail" style="background-image:url(https://img.picturecdn.com/files/article/image/1/1287/1287s.jpg)"></a>
						</div>
						<div class="4kF22 col-sm-7 pl0">
							<div class="Foeeo caption">
								<h4 class="ASXDs fs-16 text-muted"><a href="/page/detail1292.html" title="神宠又给我开挂了">神宠又给我开挂了</a></h4>
								<small class="sh9S5 fs-14 text-muted">石三</small>
								<p class="VIXfx fs-12 text-justify hidden-xs">万古八荒第一神挂!上溯三层世界,最巅峰律令!……三年前,天空坠落三个生灵。西岭秦王得其一,横扫六国统一西岭。南荒大周武曌得其一,纵横南荒十九教,登顶第一。孙长..</p>
							</div>
						</div>
					</div>
				</div>
											<div class="TccVX col-xs-4 book-coverlist">
					<div class="v9Pwk row">
						<div class="kAogg col-sm-5">
							<a href="/page/detail860.html" class="eDtiC thumbnail" style="background-image:url(https://img.picturecdn.com/files/article/image/0/855/855s.jpg)"></a>
						</div>
						<div class="lkUzL col-sm-7 pl0">
							<div class="JFM5a caption">
								<h4 class="DNS2q fs-16 text-muted"><a href="/page/detail860.html" title="上门狂婿">上门狂婿</a></h4>
								<small class="ojhVV fs-14 text-muted">狼叔当道</small>
								<p class="xOIIA fs-12 text-justify hidden-xs"> 入赘三年,受尽羞辱;扫墓归来,开启逆袭之路!</p>
							</div>
						</div>
					</div>
				</div>
											<div class="ZOyht col-xs-4 book-coverlist">
					<div class="1f2SU row">
						<div class="Fmpdx col-sm-5">
							<a href="/page/detail825.html" class="4DE5C thumbnail" style="background-image:url(https://img.picturecdn.com/files/article/image/0/820/820s.jpg)"></a>
						</div>
						<div class="GkkON col-sm-7 pl0">
							<div class="nS15F caption">
								<h4 class="vjFQk fs-16 text-muted"><a href="/page/detail825.html" title="巨甜!我在禁欲冷王的怀里恃宠而骄">巨甜!我在禁欲冷王的怀里恃宠而骄</a></h4>
								<small class="SdR5f fs-14 text-muted">浩瀚之渊</small>
								<p class="P8nkE fs-12 text-justify hidden-xs">一场事故,让恶名昭昭的医学博士江云缨穿到了相府又丑又哑的嫡女身上,开局就是与人偷腥?满级邪恶大佬华丽登场,不做柔弱小白花,谁来惹她,个个反杀!什么?渣爹要把她嫁给克妻的痴傻璃王,双腿残疾还不能人道?完美!药死他是不是可以妻承夫业?于是江云缨带着小算盘当上人人同情的璃王妃,摇身成了京都第一美人,还一边风风火火搞事业。开连锁医馆,建最大商会,立暗杀组织,各方势力纷纷栽在她手里,她还直呼不刺激!被甩满脸</p>
							</div>
						</div>
					</div>
				</div>
											<div class="uDYsa col-xs-4 book-coverlist">
					<div class="pl93M row">
						<div class="IWnsF col-sm-5">
							<a href="/page/detail131077.html" class="GHFXb thumbnail" style="background-image:url(https://img.picturecdn.com/files/article/image/131/131072/131072s.jpg)"></a>
						</div>
						<div class="iaNh7 col-sm-7 pl0">
							<div class="Mo7As caption">
								<h4 class="Q4a49 fs-16 text-muted"><a href="/page/detail131077.html" title="穿越无限之旅">穿越无限之旅</a></h4>
								<small class="LcMVz fs-14 text-muted">神人无名</small>
								<p class="vIKcM fs-12 text-justify hidden-xs">金庸武侠中有不少绝世高手,书中有提及名字的,也有不曾提及名字的,但都是拥有自己独有的绝世武功而名动天下。段誉有六脉神剑,欧阳锋有蛤蟆功,林朝英有玉女素心剑法,..</p>
							</div>
						</div>
					</div>
				</div>
								
								<div class="OiqUA clear"></div>
			</div>
		</div>
	</div>

文本获取

我们的目的是抓取本周热读推荐的所有小说名字。分析上面的结果可知,所有的名字都在标签h4里面。所有代码可以写成如下格式:

import requests
from lxml import etree

res = requests.get("http://www.biqugei.net/")

html = etree.HTML(res.text)

result = html.xpath('//h4')
print(result)

在这几行代码中,我们先将通过requests获取的html文本,使用etree.HTML类初始化,这样就构成了一个XPath解析对象。我们通过//h4查找元素的所有子孙节点h4。结果如下所示。

[<Element h4 at 0x1cbd02f5688>, <Element h4 at 0x1cbd02f5648>, <Element h4 at 0x1cbd02f5588>, <Element h4 at 0x1cbd02f55c8>, <Element h4 at 0x1cbd02f56c8>, <Element h4 at 0x1cbd02f5388>]

我们获得了小说名所在的元素,如果要获取具体的文本内容,可以使用/text()方法,修改代码如下:

result = html.xpath('//h4/text()')

运行结果如下:

[]

意外的是我们没有获取到任何文本,只有一个空集合。这是什么原因呢?因为 xpath 中 text 方法前面是/,而/的含义是选取直接子节点,很明显h4的直接子节点是a节点,文本都是在a节点的内部的,所以这里没有匹配到任何文本。因此,如果想要获取h4节点内部的文本,有两种方式,一种是先获取a节点,再获取文本。另一种是使用//获取子孙节点。

第一种方式代码如下:

result = html.xpath('//h4/a/text()')
print(result)

第二种方式代码如下:

result = html.xpath('//h4//text()')
print(result)

最终运行结果如下:

['巨甜!我在禁欲冷王的怀里恃宠而骄', '此情惟你独钟', '穿越无限之旅', '上门狂婿', '神宠又给我开挂了', '皇家的和尚']

可以看到我们获取的内容都是h4标签里面的文本。说明我们的属性匹配是正确的。

属性获取

我们已经能够通过text方法获取节点内部的文本了,那么节点的属性该怎么获取呢,比如说如何获取小说链接,也即a标签内的href属性值呢?我们可以使用@符号获取。

import requests
from lxml import etree

res = requests.get("http://www.biqugei.net/")

html = etree.HTML(res.text)

result = html.xpath('//h4/a/@href')
print(result)

运行结果如下:

['/page/detail1292.html', '/page/detail825.html', '/page/detail860.html', '/page/detail65541.html', '/page/detail1038.html', '/page/detail131077.html']

可以看到,我们成功的获取了小说链接,并返回列表。

属性值匹配

<div class="RAgOj caption">
	<h4 class="sYdCt fs-16 text-muted"><a href="/page/detail65541.html" title="皇家的和尚">皇家的和尚</a></h4>
	<small class="rI9eW fs-14 text-muted">蓅謃</small>
	<p class="UxRCn fs-12 text-justify hidden-xs">冯小宝穿越了,竟然变成了名副其实的花和尚。别人穿越都是带着王霸之气,他却只想如何活下去!大唐高宗年间,那是一个多姿多彩的时代,既有威震天下的名臣武将,李靖,..</p>
</div>

在选择节点的时候我们可能需要选择特定属性的节点,比如在以上文本中,我们想选择title皇家的和尚a标签的href值。我们还可以使用@符号过滤。

import requests
from lxml import etree

res = requests.get("http://www.biqugei.net/")

html = etree.HTML(res.text)

result = html.xpath('//h4/a[@title="皇家的和尚"]/@href')
print(result)

结果如下:

['/page/detail65541.html']

可见,我们获取了正确的小说链接。

属性多值匹配

但是,在有些时候节点的某个属性有多个值,如上面html文本中。最外面的div节点class属性有两个值RAgOjcaption。如果我们使用一下代码获取时:

result = html.xpath('//div[@class="RAgOj caption"]')
result = html.xpath('//div[@class="RAgOj"]')
result = html.xpath('//div[@class="caption"]')

结果如下:

[]

发现无法正确的获取数据。返回空列表。在这种情况下,就要使用contains方法,代码如下所示。

result = html.xpath('//div[contains(@class, "RAgOj")]')
print(result)

此时,运行结果如下:

[<Element div at 0x21ac2c044c8>]

可以看到完成了匹配。

多属性匹配

有时候,我们可能需要根据多个属性来确定一个节点,这时候就需要匹配多个属性值,可以使用运算符and连接多个属性。
html文本如下:

<li class="FQd8o list-group-item"><a class="JGfFp list-name" href="/page/detail165426.html" title="仙在囧途:天上掉下个仙妹妹">仙在囧途:天上掉下个仙妹妹</a><span class="Uq0lo pull-right fs-12">单兮</span></li>
								
<li class="dM9ix list-group-item"><a class="IX3kF list-name" href="/page/detail165482.html" title="重写九九">重写九九</a><span class="YcVhY pull-right fs-12">一桶布丁</span></li>
								
<li class="QfEts list-group-item"><a class="9w6dR list-name" href="/page/detail165530.html" title="绝世驭鬼师:邪王,要翻身!">绝世驭鬼师:邪王,要翻身!</a><span class="BHJhj pull-right fs-12">南北火</span></li>
								
<li class="sRGTS list-group-item"><a class="oLw1q list-name" href="/page/detail165557.html" title="宿命之环">宿命之环</a><span class="87T2L pull-right fs-12">爱潜水的乌贼</span></li>

如果我们要匹配重写九九这本小说的链接,可以使用以下代码获取:

result = html.xpath('//a[contains(@class, "list-name") and @title="重写九九"]/@href')
print(result)

结果如下:

['/page/detail165482.html']

按序选择

在选择节点时,如果匹配到多个数据,而我们只要某一个数据时该怎么办呢?比如我想获取以下文本最后一条数据。可以通过往括号传入索引的方式选择特定次序的数据,代码如下:

<li class="FQd8o list-group-item"><a class="JGfFp list-name" href="/page/detail165426.html" title="仙在囧途:天上掉下个仙妹妹">仙在囧途:天上掉下个仙妹妹</a><span class="Uq0lo pull-right fs-12">单兮</span></li>
								
<li class="dM9ix list-group-item"><a class="IX3kF list-name" href="/page/detail165482.html" title="重写九九">重写九九</a><span class="YcVhY pull-right fs-12">一桶布丁</span></li>
								
<li class="QfEts list-group-item"><a class="9w6dR list-name" href="/page/detail165530.html" title="绝世驭鬼师:邪王,要翻身!">绝世驭鬼师:邪王,要翻身!</a><span class="BHJhj pull-right fs-12">南北火</span></li>
								
<li class="sRGTS list-group-item"><a class="oLw1q list-name" href="/page/detail165557.html" title="宿命之环">宿命之环</a><span class="87T2L pull-right fs-12">爱潜水的乌贼</span></li>
result = html.xpath('//li[last()]/a/text()')
print(result)
['宿命之环']
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python爬虫学习之数据提取(XPath) 的相关文章

随机推荐

  • devtools安装_R语言入门之R包的安装

    R语言是一个强大的数据分析工具 其强大之处在于有各种各样的R包帮助其实现各种各样的功能 通常来说 R包的安装主要有四种方法 包括 1 从R语言官网上直接下载相关R包并安装 2 从Bioconductor上下载R包并安装 3 从Github上
  • 华为OD机试真题2022(JavaScript)

    华为OD机试真题题库已换 华为OD机试真题2023 JavaScript 本栏有100 道算法题 并提供正确解法 JavaScript 和解题思路 保证都是华为机试真题 非练习题 大概率会考到原题 大家有什么问题可以留言探讨和交流 华为机试
  • Tomcat 系统架构与设计模式之工作原理篇

    本文以 Tomcat 5 为基础 也兼顾最新的 Tomcat 6 和 Tomcat 4 Tomcat 的基本设计思路和架构是具有一定连续性的 Tomcat 总体结构 Tomcat 的结构很复杂 但是 Tomcat 也非常的模块化 找到了 T
  • MySQL 5.5.62下载、安装与卸载详细步骤

    目录 下载地址 安装过程 测试安装 卸载过程 下载地址 安装包我传到了CSDN 下载不需要积分 是从官网下载上传的 可以放心使用 CSDN下载地址 mysql 5 5 62 winx64 msi 官网下载地址 地址 安装过程 双击安装包打开
  • 计算机网络笔记Part2 物理层(Physical Layer)

    计算机网络笔记Part2 物理层 Physical Layer 一 物理层基本概念 二 数据通信 1 一个数据通信例子 2 相关术语 3 三种通讯方式 4 两种数据传输方式 5 码元 Symbol 波特 Baud 速率 带宽 Band Wi
  • 创建自定义的archetype(项目模板)

    一 archetype简介 Archetype是一个Maven项目的模板工具包 它定义了一类项目的基本架构 Archetype为开发人员提供了创建Maven项目的模板 同时它也可以根据已有的Maven项目生成参数化的模板 通过archety
  • G1垃圾回收器简介及回收过程

    一 什么是G1 同CMS一样 G1也是关注停顿时间 不过它是可控的 它被设计用来取代CMS 因为它是空间整理所以没有CMS那么严重的空间碎片问题 同时提供可控的停顿时间 特性 1 G1不同于之前的那些垃圾收集器分为连续的年轻代 老年代和永久
  • leetcode-跳跃游戏系列

    1 跳跃游戏 leetcode 55 跳跃游戏 1 问题描述 给定一个非负整数数组 n u m s nums nums 你最初位于数组的 第一个下标 数组中的每个元素代表你在该位置可以跳跃的最大长度 判断你是否能够到达最后一个下标 示例 1
  • Python-抓取小红书文章的心路历程

    在这之前从未了解过小红书 然后习惯性地百度了一下 发现是这样的 研究发现 这玩意没有pc端的接口 也就是说没办法直接从pc端抓取数据 好吧 放弃 不过pc端还是有用处的 打开社区精选 点开几个推送详情页看了看 发现所有的文章url都是htt
  • form表单中使用fileUpLoad上传文件

    在最近的项目中 需要对用户的头像就行上传 这里了解到使用appche的 大家可自行到mvn库搜索jar包名进行下载 这里需要注意的是代码中对参数的读取 正常情况下我么使用getparameter方法进行读取表单数据 但是因为在form中我们
  • 【Neo4j】第 3 章:使用 Pure Cypher 为您的业务赋能

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • A Gentle Introduction to Graph Neural Networks(一篇GNN的博客)

    图神经网络 读A Gentle Introduction to Graph Neural Networks笔记 1 直观上的理解 layer后面的标号代表是第几层 要注意每一层都是由比它更深的层相互影响的 比如layer2他可能只有laye
  • 关于专栏基于WordPress的手把手建站教程

    如何建立一个自己的个人博客 建站需要什么基础知识 建站的过程是什么 其实建站真的很容易 WordPress已经很成熟了 基本不需要什么基础知识 如何建站这也是我写的比较用心的一个教程 因此准备写一个手把手教你建站系列教程 本教程基于系统Ub
  • mac 和华为手机互传文件

    参考博客 华为手机传输文件到Mac电脑上 简书 应用场景 1 把资料从手机上的数据备份到电脑上或反向操作 2 需要把资料传给朋友的时候 有两种方式 第一种是通过数据线 传输速度快 但是需要安装软件和使用数据线 具体流程如下 1 先准备一个双
  • 异常检测主要方法总结

    最近对预测及异常检测进行了一些研究和学习 把所学东西做一个汇总整理 欢迎交流拍砖 侵权删 目录 一 时间序列概念 二 时间序列异常检测 三 时序类型 四 异常类型 4 1 点异常 4 2 上下文异常 4 3 集合异常 五 重要概念 5 1
  • 人脸识别趟坑历程

    1 人脸识别概述 人脸识别 是基于人的脸部特征信息进行身份识别的一种生物识别技术 用摄像机或摄像头采集含有人脸的图像或视频流 并自动在图像中检测和跟踪人脸 进而对检测到的人脸进行脸部的一系列相关技术 其中技术包括图像采集 特征定位 身份的确
  • jmeter3.3调用数据库写存储过程注意点

    1 数据库配置页面 2 创建存储过程要保证库里没有同名 本来这句drop语句放在创建存储过程里面的 发现会导致不会执行存储过程 一定要分开写 query type选择 update statement 3 创建存储过程 variable n
  • 5-6)视图与索引

    文章目录 视图 一 视图概述 1 视图的定义 2 视图的分类 3 视图的优缺 二 创建视图 使用T SQL 语句创建视图 创建视图注意的问题 三 使用视图 视图 视图是一种虚拟的数据表 Virtual table 来源于数据表和其他数据 一
  • 实验一:交换机的配置与管理-计算机网络

    交换机的配置与管理 技术原理 交换机的管理方式基本分为两种 带内管理和带外管理 通过交换机的Console端口管理交换机属于带外管理 这种管理方式不占用交换机的网络端口 第一次配置交换机必须利用Console端口进行配置 交换机的命令行操作
  • Python爬虫学习之数据提取(XPath)

    Python爬虫学习之数据提取XPath 概述 常用规则 运算符及介绍 准备工作 实例 文本获取 属性获取 属性值匹配 属性多值匹配 多属性匹配 按序选择 概述 XPath的全称是XML Path Language 即XML路径语言 用来在