网络爬虫之网页数据解析(XPath)
文章目录
- 引入
- 什么是XML
- XML的节点关系
- XPath定义
- XPath表达式
- 最常用的路径表达式
- 常用路径表达式以及表达式的结果
- 谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中
- 选取未知节点
- 选取若干路径,通过在路径表达式中使用“|”运算符,您可以选取若干个路径
- XPath的运算符
- lxml库
- 定义
- lxml数据转换
- lxml读取文件
- XPath具体用法
- XPath案例
引入
有人说,我正则用的不好,处理HTML文档很累,有没有其他的方法?
有!那就是XPath,我们可以先将网络获取的String类型数据转换成 HTML/XML文档,然后用 XPath 查找 HTML/XML 节点或元素。
什么是XML
大家都知道HTML,那XML又是什么呢?
- XML 指可扩展标记语言(EXtensible Markup Language)
- XML 是一种标记语言,很类似 HTML
- XML 的设计宗旨是传输数据,而非显示数据
- XML 的标签需要我们自行定义。
- XML 被设计为具有自我描述性。
- XML 是 W3C 的推荐标准
图解:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vUeRZNSF-1590634079149)(C:\Users\王利钦\Desktop\爬虫总结\XML图解1.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Pxx1cJ1-1590634079153)(C:\Users\王利钦\Desktop\爬虫总结\XML图解2.jpg)]
XML的节点关系
父、子、同胞、先辈、后代
XPath定义
XPath (XML Path Language) 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。
XPath表达式
最常用的路径表达式
通配符 描述 / 从根节点选取。 // 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置。 . 选取当前节点。 … 选取当前节点的父节点。 @ 选取属性。 常用路径表达式以及表达式的结果
表达式 结果 /bookstore 选取根元素bookstore。注释:假如路径起始于正斜杆(/),则此路径始终代表到某元素的绝对路径! bookstore/book 选取属于bookstore的子元素的所有book元素 //book 选取所有book子元素,而不管它们在文档中的位置。 bookstore//book 选取属于bookstore元素的后代的所有book元素,而不管它们位于bookstore之下的什么位置。 //@lang 选取名为lang的所有属性 谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中
路径表达式 结果 /bookstore/book[1] 选取属于bookstore子元素的第一个book元素。 /bookstore/book[last()] 选取属于bookstore子元素的最后一个book元素。 /bookstore/book[last()-1] 选取属于bookstore子元素的倒数第二个book元素。 /bookstore/book[postion()❤️] 选取最前面的两个属于bookstore元素的子元素的book元素。 //title[@lang] 选取所有拥有名为lang的属性的title元素。 //title[@lang=‘eng’] 选取所有title元素,且这些元素拥有值为eng的lang属性。 /bookstore/book[price>35.00] 选取bookstore元素的所有book元素,且其中的price元素的值须大于35.00。 /bookstore/book[price>35.00]/title 选取bookstore元素中的book元素的所有title元素,且其中的price元素的值须大于35.00。 选取未知节点
通配符 描述 * 匹配任何元素节点。 @* 匹配任何属性节点。 路径表达式 结果 /bookstore/* 选取bookstore元素的所有子元素。 //* 选取文档中的所有元素。 //title[@*] 选取所有带有属性的title元素。 选取若干路径,通过在路径表达式中使用“|”运算符,您可以选取若干个路径
路径表达式 结果 //book/title|//book/price 选取book元素的所有title和price元素。 //title|//price 选取文档中的所有title和price元素。 /bookstore/book/title|//price 选取属于bookstore元素的book元素的所有title元素,以及文档中所有的price元素。 XPath的运算符
运算符 描述 实例 返回值 | 计算两个节点集 //book|//cd 返回所有拥有book和cd元素的节点集 + 加法 6+4 10 - 减法 6-4 2 * 乘法 6*4 24 div 除法 8div4 2 = 等于 price=9.80 如果price是9.80,则返回true。如果price是9.90,则返回false。 != 不等于 price!=9.80 如果price是9.90,则返回true。如果price是9.80,则返回false。 < 小于 price<9.80 如果price是9.00,则返回true。如果price是9.90,则返回false。 <= 小于或等于 price<=9.80 如果price是9.00,则返回true。如果price是9.90,则返回false。 > 大于 price>9.80 如果price是9.90,则返回true。如果price是9.80,则返回false。 >= 大于或等于 price>=9.80 如果price是9.90,则返回true。如果price是9.70,则返回false。 or 或 price=9.80 or price=9.70 如果price是9.80或者9.70,则返回true。 and 与 price>9.00 and price<9.90 如果price是9.80,则返回true。如果price是8.50,则返回false。 mod 计算除法的余数 5 mod 2 1
lxml库
定义
lxml 是 一个HTML/XML的解析器,主要的功能是如何解析和提取 HTML/XML 数据。
lxml和正则一样,也是用 C 实现的,是一款高性能的 Python HTML/XML 解析器,我们可以利用XPath语法,来快速的定位特定元素以及节点信息。
lxml数据转换
源码
from lxml import etreestr = '''<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></ul></div> ''' #利用etree.HTML,将String字符串解析为HTML文档 html = etree.HTML(str) result = etree.tostring(html) print(result.decode('utf-8'))
所得数据
'''<div><ul><li class="item-0"><a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html">third item</a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></ul></div>
'''
lxml读取文件
源码
from lxml import etree# 读取外部文件 hello.html html = etree.parse('./hello.html') print(html)
文件数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title>测试页面</title>
</head>
<body><ol><li class="haha">醉卧沙场君莫笑,古来征战几人回</li><li class="heihei">两岸猿声啼不住,轻舟已过万重山</li><li id="hehe" class="nene">一骑红尘妃子笑,无人知是荔枝来</li><li class="xixi">停车坐爱枫林晚,霜叶红于二月花</li><li class="lala">商女不知亡国恨,隔江犹唱后庭花</li></ol><div id="pp"><div><a href="http://www.baidu.com">李白</a></div><ol><li class="huanghe">君不见黄河之水天上来,奔流到海不复回</li><li id="tata" class="hehe">李白乘舟将欲行,忽闻岸上踏歌声</li><li class="tanshui">桃花潭水深千尺,不及汪伦送我情</li></ol><div class="hh"><a href="http://mi.com">雷军</a></div><div class="jj"><b href="http://mi.com"><c>3</c></b><b href="http://mi.com"><c>5</c></b><b href="http://mi.com"><c>6</c></b><b href="http://mi.com"><c>8</c></b><b href="http://mi.com"><c>9</c></b><b href="http://mi.com"><c>3</c></b></div><ol><li class="dudu">are you ok</li><li class="meme">会飞的猪</li></ol></div>
</body>
</html>
XPath具体用法
被解析网页原码
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" /><title>测试页面</title> </head> <body><ol><li class="haha">醉卧沙场君莫笑,古来征战几人回</li><li class="heihei">两岸猿声啼不住,轻舟已过万重山</li><li id="hehe" class="nene">一骑红尘妃子笑,无人知是荔枝来</li><li class="xixi">停车坐爱枫林晚,霜叶红于二月花</li><li class="lala">商女不知亡国恨,隔江犹唱后庭花</li></ol><div id="pp"><div><a href="http://www.baidu.com">李白</a></div><ol><li class="huanghe">君不见黄河之水天上来,奔流到海不复回</li><li id="tata" class="hehe">李白乘舟将欲行,忽闻岸上踏歌声</li><li class="tanshui">桃花潭水深千尺,不及汪伦送我情</li></ol><div class="hh"><a href="http://mi.com">雷军</a></div><div class="jj"><b href="http://mi.com"><c>3</c></b><b href="http://mi.com"><c>5</c></b><b href="http://mi.com"><c>6</c></b><b href="http://mi.com"><c>8</c></b><b href="http://mi.com"><c>9</c></b><b href="http://mi.com"><c>3</c></b></div><ol><li class="dudu">are you ok</li><li class="meme">会飞的猪</li></ol></div> </body> </html>
获取所有的< li >标签
from lxml import etreehtml = etree.parse('hello.html') li_list = html.xpath('//li')print(li_list) # 打印<li>标签的元素集合 print(len(li_list))
继续获取< li > 标签的所有 class属性
from lxml import etreehtml = etree.parse('hello.html') result = html.xpath('//li/@class') print(result)
继续获取< li >标签下href为 link1.html 的 < a > 标签
from lxml import etree html = etree.parse('./hello.html') result = html.xpath('//li/a[@href="link1.html"]') print(result)
获取< li >标签下的所有< span >标签
from lxml import etree data = ''' <div><ul><li class="item-0">你好,老段<a href="link1.html">first item</a></li><li class="item-1"><a href="link2.html">second item</a></li><li class="item-inactive"><a href="link3.html"><span class="bold">third item</span></a></li><li class="item-1"><a href="link4.html">fourth item</a></li><li class="item-0"><a href="link5.html">fifth item</a></li></ul></div>''' html = etree.HTML(data) result = html.xpath('//li//span') print(result[0].text)
获取< li >标签下的< a >标签的所有class
# 获取 <li> 标签下的<a>标签里的所有 class from lxml import etree html = etree.parse('hello.html') result = html.xpath('//li/a//@class')print(result)
获取最后一个< li >的< a >的href
from lxml import etreexml = etree.parse('./hello.html')result = xml.xpath('//li[last()]/a/@href')print(result)
获取倒数第二个元素的内容
from lxml import etreehtml = etree.parse('hello.html') result = html.xpath('//li[last()-1]/a') print(result[0].text) print(result)
获取class值为bold的标签名
# 获取 class 值为 bold 的标签名 from lxml import etree html = etree.parse('hello.html') result = html.xpath('//*[@class="bold"]') # tag方法可以获取标签名 print(result[0].tag) print(result[0].text)
条件使用
- 获取文本数据://li[@id=“hehe”]/text()
- 包含某个条件://li[contains(@class,“h”)]
- 等于某个条件://div[@id=“pp”]/ol[last()]/li/@*
- 条件并用://li[@id=“hehe”] [@class=“nene”]/text()
XPath案例
import requests
from lxml import etree
url1 = 'https://www.neihanba.com/dz/'
url = 'https://www.neihanba.com/dz/list_%d.html'
if __name__ == '__main__':fp = open('./duanzi.csv',mode = 'a',encoding='utf-8')for i in range(1,101):if i == 1:url_duanzi = url1else:url_duanzi = url%(i)response = requests.get(url_duanzi)response.encoding = 'gbk'content = response.texthtml = etree.HTML(content)result = html.xpath('//ul[@class="piclist longList"]/li')for li in result:try:title = li.xpath('.//h4/a/b/text()')[0]content = li.xpath('.//div[@class="f18 mb20"]/text()')[0].strip().strip('\n')info = ''.join(li.xpath('.//div[@class="ft"]/span//text()')[1:])fp.write('%s\t%s\t%s\n'%(title,content,info))except Exception as e:# 异常保存,第二天,分析,单独爬取。passprint('第%d页内容保存成功!'%(i))fp.close()# !!!缺少异常捕获
网络爬虫之网页数据解析(XPath)相关推荐
- 网络爬虫之网页数据解析(bs4)
文章目录 定义 实例数据 遍历文档树 搜索文档树 CSS选择器 bs4实例 定义 和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HT ...
- java爬取网页数据_Python网络爬虫实战(二)数据解析
Python网络爬虫实战 (二)数据解析 本系列从零开始阐述如何编写Python网络爬虫,以及网络爬虫中容易遇到的问题,比如具有反爬,加密的网站,还有爬虫拿不到数据,以及登录验证等问题,会伴随大量网站 ...
- python爬虫程序详解_Python网络爬虫之三种数据解析方式
指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指定数据解析.因为大多数情况下的需求,我们都会指 ...
- python爬虫解析数据包_Python网络爬虫之三种数据解析方式
引入 回顾requests实现数据爬取的流程 指定url 基于requests模块发起请求 获取响应对象中的数据 进行持久化存储 其实,在上述流程中还需要较为重要的一步,就是在持久化存储之前需要进行指 ...
- Python网络爬虫实战(二)数据解析
上一篇说完了如何爬取一个网页,以及爬取中可能遇到的几个问题.那么接下来我们就需要对已经爬取下来的网页进行解析,从中提取出我们想要的数据. 根据爬取下来的数据,我们需要写不同的解析方式,最常见的一般都是 ...
- 数据爬取 mail_Python网络爬虫实战,数据解析!
上一篇说完了如何爬取一个网页,以及爬取中可能遇到的几个问题.那么接下来我们就需要对已经爬取下来的网页进行解析,从中提取出我们想要的数据. 根据爬取下来的数据,我们需要写不同的解析方式,最常见的一般都是 ...
- Python网络爬虫实战,数据解析!
上一篇说完了如何爬取一个网页,以及爬取中可能遇到的几个问题.那么接下来我们就需要对已经爬取下来的网页进行解析,从中提取出我们想要的数据. 根据爬取下来的数据,我们需要写不同的解析方式,最常见的一般都是 ...
- beautifulsoup网页爬虫解析_Python3 网络爬虫快速入门实战解析
点击上方"Python高校",关注 文末干货立马到手 作者:Jack Cui http://cuijiahua.com/blog/2017/10/spider_tutorial_1 ...
- python3 爬虫实例_【实战练习】Python3网络爬虫快速入门实战解析(上)
原标题:[实战练习]Python3网络爬虫快速入门实战解析(上) 摘要 使用python3学习网络爬虫,快速入门静态网站爬取和动态网站爬取 [ 前言 ] 强烈建议:请在电脑的陪同下,阅读本文.本文以实 ...
最新文章
- java robot 控制鼠标_Java-探索Robot类:[2]自动控制鼠标
- 那些参加过创业赛事活动的创业者后来怎么样了?
- BCGSoft Demo示例展示:菜单示例集合(2/2)
- JS-获取class类名为某个的元素-【getClass】函数封装
- 使用Anemometer基于pt-query-digest将MySQL慢查询可视化
- Dx11DemoBase 基类(二) 初始化 DirectX11 的 4个基本步骤
- 英特尔开源WebRTC开发套件OWT
- C++ 普通函数与函数模板 区别以及调用规则01
- 程序员应该具备的素质(来自csdn)
- php调接口post,php模拟post提交请求,调用接口
- MYSQL 编码设置
- 自动门程序c语言,自动门控制程序共享
- linux网卡pci信息,在进行CGKlinux系统网络配置时,使用()命令可以查询出网卡的PCI编号与设备名的对应关系。...
- java技术栈_七天串起java技术栈-开篇
- mysql报错1241_flask内的mysql插入语句报错:1241, 'Operand should contain 1 column(s)
- IE Cookie 文件格式
- 简析struct in_addr ,struct sockadd
- 本文介绍在Wireshark网络协议分析仪中如果解密SSL和TLS流量
- UVALive - 5857 Captain Q's Treasure
- 查看Andriod内置浏览器WebView版本