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属性有两个值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)
['宿命之环']

Python爬虫学习之数据提取(XPath)相关推荐

  1. Python爬虫学习之数据提取(Beautiful Soup)

    Python爬虫学习之数据提取Beautiful Soup 前期回顾 概述 解析器 准备工作 实例 节点选择器 方法选择器 find_all find 总结 前期回顾 Python爬虫学习之reque ...

  2. [Python爬虫] 六、数据提取之XPath与lxml类库

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...

  3. Python爬虫学习实战

    Python爬虫学习实战 前期回顾 概述 技术要求 实战 网页分析与数据提取 小说目录提取 小说章节内容 总结 前期回顾 Python爬虫学习之requests Python爬虫学习之数据提取(XPa ...

  4. [Python爬虫] 三、数据抓取之Requests HTTP 库

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 一.urllib 模块 所谓网页抓取,就是把URL ...

  5. [Python爬虫] 四、数据抓取之HTTP/HTTPS抓包工具Fiddler

    往期内容提要: [Python爬虫] 一.爬虫原理之HTTP和HTTPS的请求与响应 [Python爬虫] 二.爬虫原理之定义.分类.流程与编码格式 [Python爬虫] 三.数据抓取之Request ...

  6. Python爬虫学习第三章-4.3-使用xpath解析爬取全国城市名称

    Python爬虫学习第三章-4.3-使用xpath解析爬取全国城市名称   这一节主要是使用xpath解析爬取全国城市名称 这里使用的网址是:空气质量历史数据查询   这一个案例体现的点主要是xpat ...

  7. 从入门到入土:Python爬虫学习|实例练手|爬取猫眼榜单|Xpath定位标签爬取|代码

    此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...

  8. 从入门到入土:Python爬虫学习|实例练手|爬取新浪新闻搜索指定内容|Xpath定位标签爬取|代码注释详解

    此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...

  9. 从入门到入土:Python爬虫学习|实例练手|爬取百度产品列表|Xpath定位标签爬取|代码注释详解

    此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) 本人博客所有文章纯属学习之用,不涉及商业利益.不合适引用,自当删除! 若 ...

最新文章

  1. 存储过程授权给子用户
  2. iOS 消息推送原理及实现总结
  3. 关于寻路算法的一些思考(4):A* 算法的变体
  4. C和指针之动态内存分配malloc、calloc、realloc简单使用和区别
  5. 第55课 分解质因数 《小学生C++编程入门》
  6. Mysql学习总结(64)——Mysql配置文件my.cnf各项参数解读
  7. MySql-触发器操作
  8. DateUtils工具类
  9. EXCEL导入SQL的语句
  10. 高性能mysql 3 pdf下载_《高性能MySQL_第3版》PDF版本下载
  11. Oracle批量导出Hive建表语句
  12. Python金融大数据分析——第11章 统计学(2)投资组合优化 笔记
  13. 中华酷联小米:未来谁将干掉三星?
  14. java中闰月_java 实现万年历
  15. 谈谈 MVX 中的 Model
  16. 路在脚下,何去何从?
  17. 华为AI人工智能辅助宫颈癌筛查系统, 病理诊断更智能
  18. 微信签名错误解决步骤
  19. 南京大学计算机2021年考研,2021年南京大学计算机科学与技术(081200)考研专业目录_硕士研究生考试范围 - 学途吧...
  20. DELL R710做raid5图解

热门文章

  1. 1207. 独一无二的出现次数
  2. .Net Core能令微软的C#迎来转机吗?
  3. python网页优化_400% 的飞跃-web 页面加载速度优化实战
  4. Deep Feedback Network for Recommendation
  5. MT4插件开发 之 通过managerAPI获取实时行情数据
  6. 计算机网络专业知识与技能大赛,【计算机网络论文】技能大赛与中职计算机教学的融合(共2907字)...
  7. MathJax基本的使用方式
  8. COMSOL中场路耦合实现及方法对比
  9. oracle+app_query,query用法
  10. L2-028 秀恩爱分得快(异或+暴力)