Python爬虫学习之数据提取(XPath)
Python爬虫学习之数据提取XPath
- 概述
- 常用规则
- 运算符及介绍
- 准备工作
- 实例
- 文本获取
- 属性获取
- 属性值匹配
- 属性多值匹配
- 多属性匹配
- 按序选择
概述
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 requestsres = 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 etreeres = 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 etreeres = 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 etreeres = 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
属性有两个值RAgOj
和caption
。如果我们使用一下代码获取时:
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)
['宿命之环']
Python爬虫学习之数据提取(XPath)相关推荐
- Python爬虫学习之数据提取(Beautiful Soup)
Python爬虫学习之数据提取Beautiful Soup 前期回顾 概述 解析器 准备工作 实例 节点选择器 方法选择器 find_all find 总结 前期回顾 Python爬虫学习之reque ...
- [Python爬虫] 六、数据提取之XPath与lxml类库
往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...
- Python爬虫学习实战
Python爬虫学习实战 前期回顾 概述 技术要求 实战 网页分析与数据提取 小说目录提取 小说章节内容 总结 前期回顾 Python爬虫学习之requests Python爬虫学习之数据提取(XPa ...
- [Python爬虫] 三、数据抓取之Requests HTTP 库
往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 一.urllib 模块 所谓网页抓取,就是把URL ...
- [Python爬虫] 四、数据抓取之HTTP/HTTPS抓包工具Fiddler
往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...
- Python爬虫学习第三章-4.3-使用xpath解析爬取全国城市名称
Python爬虫学习第三章-4.3-使用xpath解析爬取全国城市名称 这一节主要是使用xpath解析爬取全国城市名称 这里使用的网址是:空气质量历史数据查询 这一个案例体现的点主要是xpat ...
- 从入门到入土:Python爬虫学习|实例练手|爬取猫眼榜单|Xpath定位标签爬取|代码
此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...
- 从入门到入土:Python爬虫学习|实例练手|爬取新浪新闻搜索指定内容|Xpath定位标签爬取|代码注释详解
此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...
- 从入门到入土:Python爬虫学习|实例练手|爬取百度产品列表|Xpath定位标签爬取|代码注释详解
此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...
最新文章
- 存储过程授权给子用户
- iOS 消息推送原理及实现总结
- 关于寻路算法的一些思考(4):A* 算法的变体
- C和指针之动态内存分配malloc、calloc、realloc简单使用和区别
- 第55课 分解质因数 《小学生C++编程入门》
- Mysql学习总结(64)——Mysql配置文件my.cnf各项参数解读
- MySql-触发器操作
- DateUtils工具类
- EXCEL导入SQL的语句
- 高性能mysql 3 pdf下载_《高性能MySQL_第3版》PDF版本下载
- Oracle批量导出Hive建表语句
- Python金融大数据分析——第11章 统计学(2)投资组合优化 笔记
- 中华酷联小米:未来谁将干掉三星?
- java中闰月_java 实现万年历
- 谈谈 MVX 中的 Model
- 路在脚下,何去何从?
- 华为AI人工智能辅助宫颈癌筛查系统, 病理诊断更智能
- 微信签名错误解决步骤
- 南京大学计算机2021年考研,2021年南京大学计算机科学与技术(081200)考研专业目录_硕士研究生考试范围 - 学途吧...
- DELL R710做raid5图解
热门文章
- 1207. 独一无二的出现次数
- .Net Core能令微软的C#迎来转机吗?
- python网页优化_400% 的飞跃-web 页面加载速度优化实战
- Deep Feedback Network for Recommendation
- MT4插件开发 之 通过managerAPI获取实时行情数据
- 计算机网络专业知识与技能大赛,【计算机网络论文】技能大赛与中职计算机教学的融合(共2907字)...
- MathJax基本的使用方式
- COMSOL中场路耦合实现及方法对比
- oracle+app_query,query用法
- L2-028 秀恩爱分得快(异或+暴力)