在之前的学习中了解了如何使用爬虫向目标服务器发送请求并获取响应,而此后便是要对响应进行处理,这里的处理在爬虫中通常指的是数据解析,即将相应内容数据化以方便我们进行有效数据的提取。在此过程中,有许多解析数据的方法,本节介绍利用Xpath和lxml库来解析数据。

Xpath

Xpath(全称XML Path Language,XML路径语言),是一门在XML和HTML文档中查找信息的语言,它提供了非常简明的路径选择表达式,可用来对网页的元素及属性进行遍历查找。

语法规则:

1.选取节点

XPath 使用路径表达式来选取 XML 文档中的节点或者节点集。

表达式 描述 示例 说明
nodename 选取此节点的所有子节点 div 选取div下所有子节点
/ 从当前节点选取直接子节点 /div 从根元素下选取所有div节点
// 从当前节点选取所有子孙节点 //div 从全局节点中选取所有的div节点
@ 选取属性 //a[@class] 选取所有拥有class属性的a节点
. 选取当前节点 .//a 选取当前节点下的所有a节点
.. 选取当前节点的父节点 ..//a 选取当前节点父节点下的所有a节点

2.谓语

谓语用来查找某个特定的节点或者包含某个指定的值的节点,被嵌在方括号中。

表达式 描述 示例 说明
[index] 选取指定序列的节点 /div/p[1] 选取div下的第一个p节点
[last()] 选取最后一个节点 /div/p[last()] 选取div下的最后一个p节点
[position()<?>index] 选取满足指定序列表达式的节点 //p[position()<3] 选取全局节点中的前两个p节点
[@attr<?>value] 选取属性attr满足表达式的节点 //p[@class=”text”] 选取属性class为text的p节点
[contains()] 模糊匹配 //p[contains(@class,”for”)] 选取属性class中包含’for’字符串的p节点

3.通配符

通配符,顾名思义指匹配所有节点,在爬虫中通配符用的不多,主要有如下两种:

表达式 描述 示例 说明
* 匹配任意节点 //div/* 选取div下的所有节点
@* 匹配任意拥有属性的节点 //div[@*] 选取拥有属性的所有div节点

4.选择多个路径

在Xpath路径选择表达式中可以通过在表达式中使用“|”运算符选取若干个路径。如表达式”//div | //div/p”表示选取所有div节点及其下的p节点。

5.运算符

在Xpath表达式中可以包含运算符,其中共有14种运算符,包括’|’ , ’+’ , ’-‘ , ’*’ , ’div’ , ’=’, ’!=’ , ’<‘ , ’<=’ , ’>’ , ’>=’, ’or’ , ’and‘ , ’mod’,这些表达式含义比较明了,其通常运用于谓语中,如” //div[@class='text' and @id='description']”表示选取class属性为’text’且id为’description’的div节点。

lxml库

lxml 是一个HTML/XML解析器,主要功能是解析和提取 HTML/XML 数据。lxml和正则一样由C实现,是一款高性能的 Python HTML/XML 解析器,利用它和XPath语法可以快速定位特定元素及节点以捕获信息。在此介绍如何利用lxml获取HTML文档对象。

安装方法

使用pip进行安装:pip install lxml

基本使用

##示例1——使用lxml.etree模块获取HTML对象
from lxml import etree# 网页源代码
text = """
<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></li></ul></div>
"""# 使用etree.HTML()方法获取_Element对象,传入参数为待解析的源代码
htmlElement = etree.HTML(text)# 返回htmlElement的类型
print(type(htmlElement))# 返回htmlElement的内容
print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))

由上述结果可知,etree.HTML()返回的是一个<class 'lxml.etree._Element'>的对象,因此在获取源代码内容时还需要使用tostring的方法将其进行字符编码转化,且在转化后我们可以留意到其会自动地将源代码结构补充完整。

除了直接对HTML字符串进行解析外,我们也可以对html文件进行解析。

##示例2——使用lxml.etree对html文件进行解析
from lxml import etree# xml方式解析
def parse_file_xml():htmlElement = etree.parse("myfile.html")print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))# html方式解析
def parse_file_html():parser = etree.HTMLParser(encoding='utf-8')htmlElement = etree.parse('myfile.html',parser=parser)print(etree.tostring(htmlElement, encoding='utf-8').decode('utf-8'))if __name__ =='__main__':print('\nxml文件解析')parse_file_xml()print('\nhtml文件解析')parse_file_html()

在示例2中,我们使用了两种解析html文件的方法,这主要是为了应对一些不规范HTML网页(比如有的Tag标签未匹配dui应)而采取的措施,etree解析器默认为XML方式解析,然而当解析一个不规范页面时就会产生错误,因此有时候就有必要设置特定的解析器(parser)来解析页面。

Xpath与lxml结合使用数据解析示例

在解析数据过程中,lxml用于产生源代码的_Element对象,而Xpath则是作用于_Element对象之上进行节点的检索,故解析基本思路为先通过lxml获取对象,然后利用Xpath对其进行节点检索。下面先通过几个小例子说明二者的基本使用,然后再以一个较为综合的示例来说明具体的解析流程。

<!源代码>
<table class="tablelist" cellpadding="0" cellspacing="0"><tr class="even"><td class="l square"><a target="_blank" href="position_detail.php?id=44256&keywords=&tid=0&lid=2218">25664-技术运营工程师(深圳)</a></td><td>技术类</td><td>2</td><td>深圳</td><td>2018-09-16</td></tr><tr class="odd"><td class="l square"><a target="_blank" href="position_detail.php?id=44252&keywords=&tid=0&lid=2218">15570-3D场景设计师(深圳)</a></td><td>设计类</td><td>1</td><td>深圳</td><td>2018-09-16</td></tr><tr class="even"><td class="l square"><a target="_blank" href="position_detail.php?id=44253&keywords=&tid=0&lid=2218">18425-国际支付产品软件测试工程师</a><spanclass="hot">&nbsp;</span></td><td>技术类</td><td>2</td><td>深圳</td><td>2018-09-16</td></tr>
</table>

##示例3——使用html.xpath选取节点(其返回的是一个列表)
from lxml import etree# 设置解析器并获取_Element对象
parser = etree.HTMLParser(encoding='utf-8')
html = etree.parse('example.html',parser=parser)# 获取所有tr标签
trs = html.xpath('//tr')    #[<Element tr at 0x2132da8c6c8>, <Element tr at 0x2132da8c708>, <Element tr at 0x2132da8c748>]# 获取第2个tr标签
tr2 = html.xpath('//tr[2]')[0]    #<Element tr at 0x2132da8c708># 获取所有class等于even的tr标签
tags= html.xpath('//tr[@class="even"]')    #[<Element tr at 0x20cd0b736c8>, <Element tr at 0x20cd0b73748>]# 获取所有a标签的href属性
hrefs = html.xpath('//a/@href')
#或hrefs = [element.get('href') for element in html.xpath('//a')]
‘’’
Output:
['position_detail.php?id=44256&keywords=&tid=0&lid=2218', 'position_detail.php?id=44252&keywords=&tid=0&lid=2218', 'position_detail.php?id=44253&keywords=&tid=0&lid=2218']
’’’

在上述简单介绍后便可以开始一个相对完整的网页数据解析,还是以上述源代码为例,具体如下:

##示例4——综合演练,获取网页上所有职位信息
from lxml import etree# 获取_Element对象
parser = etree.HTMLParser(encoding='utf-8')
html = etree.parse('tencent.html',parser=parser)# 获取所有tr节点,并设置存放数据的容器position
trs = html.xpath('//tr')
positions = []# 依次遍历节点并存储数据
for tr in trs:href = tr.xpath('.//a/@href')[0]  title = tr.xpath('.//td[1]//text()')[0]category = tr.xpath('./td[2]//text()')[0]nums = tr.xpath('./td[3]//text()')[0]address = tr.xpath('./td[4]//text()')[0]pub_time = tr.xpath('./td[5]//text()')[0]data = {'url':href,'title':title,'category':category,'nums':nums,'address':address,'pub_time':pub_time}positions.append(data)for position in positions:print(position)

这里要注意的是,在解析数据时我们所写的表达式中前面都有一个’.’表示选取当前节点之下的指定路径的节点,如果缺少则指定为根节点下或全局节点,由此会出现错误。由于Xpath返回的是一个列表,所以获取具体对象时需要添加[0]操作;另外,对于节点的文本字符串,可以利用函数text()来获取。


转载于:https://www.cnblogs.com/Unikfox/p/9657462.html

【Python爬虫学习笔记4】结合Xpath与lxml库解析数据相关推荐

  1. Python爬虫学习笔记 -- 爬取糗事百科

    Python爬虫学习笔记 -- 爬取糗事百科 代码存放地址: https://github.com/xyls2011/python/tree/master/qiushibaike 爬取网址:https ...

  2. python爬虫学习笔记3.2-urllib和request练习

    python爬虫学习笔记3.2-urllib和request练习 一.urllib练习 1.百度贴吧案例 需求 分析 手动测试查询流程 观察页面 分析特殊部分 https://tieba.baidu. ...

  3. python爬虫学习笔记 1.9 (Handler处理器 和 自定义Opener)

    python爬虫学习笔记 1.1(通用爬虫和聚焦爬虫) python爬虫学习笔记 1.2 ( HTTP和HTTPS ) python爬虫学习笔记 1.3 str和bytes的区别 python爬虫学习 ...

  4. python爬虫学习笔记 3.9 (了解参考:训练Tesseract)

    python爬虫学习笔记 3.9 (了解参考:训练Tesseract) 参考阅读:训练Tesseract 要使用 Tesseract 的功能,比如后面的示例中训练程序识别字母,要先在系统中设置一 个新 ...

  5. python爬虫学习笔记2模拟登录与数据库

    前言 为了加入学校里面一个技术小组,我接受了写一个爬取学校网站通知公告的任务.这个任务比以前写的爬虫更难的地方在于,需要模拟登录才能获得页面,以及将得到的数据存入数据库. 本文按照日期来记录我完成任务 ...

  6. Python爬虫学习笔记(一)

    爬虫目的: 就是根据规则抓取指定的数据,一般是大量数据 可以做爬虫的语言: PHP:多进程多线程处理不好 Java:没毛病,就是代码复杂点,修改费劲,重构成本大(为突出PY强行黑) C,C++:这都是 ...

  7. python爬虫学习笔记-网络爬虫的三种数据解析方式

    爬虫的分类 1.通用爬虫:通用爬虫是搜索引擎(Baidu.Google.Yahoo等)"抓取系统"的重要组成部分.主要目的是将互联网上的网页下载到本地,形成一个互联网内容的镜像备份 ...

  8. Python 爬虫学习笔记

    环境篇 Python3 + Pip 环境配置 MongoDB .MYSQL.Redis 环境配置 爬虫常用库安装 基础篇 基本原理 什么是爬虫:请求网站并提取数据的自动化程序 爬虫基本流程:发起请求 ...

  9. Python爬虫学习笔记

    requests模块介绍 requests模块,python中原生的一款基于网络请求的模块 作用:模拟浏览器发请求 如何使用(requests模块的编码流程): 指定url 发起请求(post请求Aj ...

最新文章

  1. python操作excel-openpyxl(1)
  2. 使MySQL 支持繁体字
  3. [导入]较为周全的Asp.net提交验证方案 (下)
  4. vs2008界面查看
  5. 10步骤优化SQL Server 数据库性能
  6. 李飞飞等6名华人入选ACM 2018 Fellow,无国内学者入选
  7. innodb的锁时间
  8. 不能bostype没有元数据异常_手把手教你用Python画个箱形图,找出“脏数据”
  9. xilinx sdk退出Debug模式回到C开发布局
  10. JAVA 内部类(innerclasses)
  11. html插一置顶图片,HTML实现置顶--火箭置顶
  12. 局域网抢速,局域网抢网速软件下载,p2p终结者和反p2p终结
  13. GIS+BIM专题二:SuperMap对接DGN数据流程
  14. 《股票大作手操盘术--杰西.利弗莫尔》
  15. 饥荒控制台输入没用_饥荒控制台怎么开启 饥荒控制台怎么用
  16. 自动驾驶技术-环境感知篇:V2X技术的介绍
  17. 你需要知道的WAMP5
  18. android高德地图定位是准确的吗,高德地图定位不准确?原因在这里!
  19. Pandas初体验——头歌平台答案
  20. 《C#零基础入门之百识百例》(九十一)预处理器指令 -- 代码示例

热门文章

  1. 张亚勤院士谈“智能计算新趋势”
  2. 为什么信不过AI看病?数据集小、可靠性差,AI医疗任重道远
  3. 2021年5G发展展望
  4. 一文剖析2020年最火十大物联网应用|IoT Analytics 年度重磅报告出炉!
  5. 学界 | 史上最强GAN图像生成器,Inception分数提高两倍
  6. LeCun:现在还没有真正的AI系统,机器与生物系统差远了
  7. 智能产品AI服务智商的权重研究|未来研究
  8. 苹果新功能惹众怒,4000 多家组织和个人签署公开信,敦促苹果放弃“儿童安全”功能...
  9. 这个勒索软件也太菜了!
  10. 16 岁的雅虎问答,因“不再受欢迎”将永久关闭