Python3 爬虫学习笔记 C07 【解析库 lxml】


Python3 爬虫学习笔记第七章 —— 【解析库 lxml】

文章目录

  • 【7.1】关于 lxml
  • 【7.2】使用 XPath
  • 【7.3】查找所有节点
  • 【7.4】查找子节点
  • 【7.5】查找父节点
  • 【7.6】属性匹配
  • 【7.7】文本获取
  • 【7.8】属性获取
  • 【7.9】一个属性包含多个值的匹配
  • 【7.10】多个属性匹配一个节点
  • 【7.11】按顺序选择节点
  • 【7.12】节点轴选择


【7.1】关于 lxml

lxml 是 Python 的一个解析库,支持 HTML 和 XML 的解析,支持 XPath 解析方式,解析效率非常高,使用前需要用命令 pip3 install lxml 安装 lxml 库

【7.2】使用 XPath

XPath(XML Path Language)即 XML 路径语言, lxml 解析库使用的正是 XPath 语法,最初是用来搜寻 XML 文档的,是一门在 XML 文档中查找信息的语言,它同样适用于 HTML 文档的搜索

XPath 常用规则

表达式描述
nodename选取此节点的所有子节点
/从当前节点选取直接子节点
//从当前节点选取子孙节点
.选取当前节点
选取当前节点的父节点
@选取属性
*通配符,选择所有元素节点与元素名
@*选取所有属性
[@attrib]选取具有给定属性的所有元素
[@attrib=‘value’]选取给定属性具有给定值的所有元素
[tag]选取所有具有指定元素的直接子节点
[tag=‘text’]选取所有具有指定元素并且文本内容是text节点

浏览器插件 XPath Helper,在线验证 XPath,谷歌商店下载地址:https://chrome.google.com/webstore/detail/hgimnogjllphhhkhlmebbmlgjoejdpjl

XPath 基本使用方法:首先使用代码 from lxml import etree导入库,然后将 HTML 文档变成一个对象,再调用对象的方法去查找指定的节点,方法有两种:tree = etree.parse() 为本地文件查找,tree = etree.HTML() 为网络文件查找,再使用语句 tree.xpath() 查找指定节点。

【7.3】查找所有节点

新建一个 xpath.html 本地文件,内容如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><title>xpath测试</title>
</head>
<body>
<div class="song">火药<b>指南针</b><b>印刷术</b>造纸术
</div>
<div class="tang"><ul><li class="balove">停车坐爱枫林晚,霜叶红于二月花。</li><li id="hua">商女不知亡国恨,隔江犹唱后庭花。</li><li class="love" name="yang">一骑红尘妃子笑,无人知是荔枝来。</li><li id="bei">葡萄美酒夜光杯,欲饮琵琶马上催。</li><li><a href="http://www.baidu.com/">百度一下</a> </li></ul><ol><li class="balucy">寻寻觅觅冷冷清清,凄凄惨惨戚戚。</li><li class="lily">咋暖还寒时候,最难将息。</li><li class="lilei">三杯两盏淡酒。</li><li>怎敌他晚来风急。</li><li>雁过也,正伤心,却是旧时相识。</li><li>爱情三十六计</li><li>什么是爱情</li></ol>
</div>
</body>
</html>

查找所有节点:

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//*')
print(result)

使用 * 代表匹配所有节点,整个 xpath.html 文件中的所有节点都会被获取到,返回形式是一个列表,每个元素是 Element 类型,其后跟了节点的名称,如 html、body、div、ul、li、a 等,所有节点都包含在列表中,输出结果如下:

[<Element html at 0x1a836a34508>, <Element head at 0x1a836a344c8>, <Element meta at 0x1a836a345c8>, <Element title at 0x1a836a34608>, <Element body at 0x1a836a34648>, <Element div at 0x1a836a346c8>, <Element b at 0x1a836a34708>, <Element b at 0x1a836a34748>, <Element div at 0x1a836a34788>, <Element ul at 0x1a836a34688>, <Element li at 0x1a836a347c8>, <Element li at 0x1a836a34808>, <Element li at 0x1a836a34848>, <Element li at 0x1a836a34888>, <Element li at 0x1a836a348c8>, <Element a at 0x1a836a34908>, <Element ol at 0x1a836a34948>, <Element li at 0x1a836a34988>, <Element li at 0x1a836a349c8>, <Element li at 0x1a836a34a08>, <Element li at 0x1a836a34a48>, <Element li at 0x1a836a34a88>, <Element li at 0x1a836a34ac8>, <Element li at 0x1a836a34b08>]

【7.4】查找子节点

通过 /// 即可查找元素的子节点或子孙节点:

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//ul/li')
print(result)

选择 ul 节点的所有直接 li 子节点:

[<Element li at 0x2a094d044c8>, <Element li at 0x2a094d045c8>, <Element li at 0x2a094d04608>, <Element li at 0x2a094d04648>, <Element li at 0x2a094d04688>]

【7.5】查找父节点

知道了子节点,也可以用 或者 parent:: 查找其父节点

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//ol/../@class')
print(result)
from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//ol/parent::*/@class')
print(result)

先查找到 ol 节点,随后获取其父节点以及其 class 属性:

['tang']

【7.6】属性匹配

有时候 HTML 包含多个相同名的节点,而节点的属性是不一样的,此时可以用 @ 符号进行属性过滤

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//li[@class="balucy"]')
print(result)

xpath.html 文件中,只有一个 class 为 balucy 的节点:<li class="balucy">寻寻觅觅冷冷清清,凄凄惨惨戚戚。</li>,运行以上代码将返回一个该元素:

[<Element li at 0x16e53aa54c8>]

【7.7】文本获取

使用 text() 方法即可提取节点中的文本:

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//li[@class="balucy"]/text()')
print(result)

输出结果:

['寻寻觅觅冷冷清清,凄凄惨惨戚戚。']

再次观察 xpath.html 文件中的 <ol></ol>这一部分:

<ol><li class="balucy">寻寻觅觅冷冷清清,凄凄惨惨戚戚。</li><li class="lily">咋暖还寒时候,最难将息。</li><li class="lilei">三杯两盏淡酒。</li><li>怎敌他晚来风急。</li><li>雁过也,正伤心,却是旧时相识。</li><li>爱情三十六计</li><li>什么是爱情</li>
</ol>

如果我们想要提取 <li> 节点里面所有的文本,就可以使用 html.xpath('//ol/li/text()') 语句:

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//ol/li/text()')
print(result)

输出结果:

['寻寻觅觅冷冷清清,凄凄惨惨戚戚。', '咋暖还寒时候,最难将息。', '三杯两盏淡酒。', '怎敌他晚来风急。', '雁过也,正伤心,却是旧时相识。', '爱情三十六计', '什么是爱情']

同样还有另一种方法,使用 html.xpath('//ol//text()') 语句,// 将会选取所有子孙节点的文本,<ol><li> 节点下的换行符也将被提取出来:

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//ol//text()')
print(result)

输出结果:

['\n        ', '寻寻觅觅冷冷清清,凄凄惨惨戚戚。', '\n        ', '咋暖还寒时候,最难将息。', '\n        ', '三杯两盏淡酒。', '\n        ', '怎敌他晚来风急。', '\n        ', '雁过也,正伤心,却是旧时相识。', '\n        ', '爱情三十六计', '\n        ', '什么是爱情', '\n    ']

【7.8】属性获取

与属性匹配一样,属性获取仍然使用 @

from lxml import etreehtml = etree.parse('./xpath.html')
result = html.xpath('//ul/li[5]/a/@href')
print(result)

获取 href 属性:

['http://www.baidu.com/']

【7.9】一个属性包含多个值的匹配

某个节点的某个属性可能有多个值,例如:

<li class="li li-first"><a href="link.html">first item</a></li> 

li 节点的 class 属性有 li 和 li-first 两个值,如果使用 html.xpath('//li[@class="li"] 语句,将无法成功匹配,这时就需要使用 contains 方法了,第一个参数传入属性名称,第二个参数传入属性值,只要此属性包含所传入的属性值,就可以完成匹配了

from lxml import etree
text = '''  
<li class="li li-first"><a href="link.html">first item</a></li>  
'''
html = etree.HTML(text)
result = html.xpath('//li[contains(@class, "li")]/a/text()')
print(result)

输出结果:

['first item']

【7.10】多个属性匹配一个节点

XPath 还可以根据多个属性来确定一个节点,这时就需要同时匹配多个属性。此时可以使用运算符 and 来连接:

from lxml import etree
text = '''  
<li class="li" name="item"><a href="link.html">first item</a></li>
'''
html = etree.HTML(text)
result = html.xpath('//li[@class="li" and @name="item"]/a/text()')
print(result)

输出结果:

['first item']

示例中运用了运算符 and 来连接,此外常见的运算符如下:

运算符描述实例返回值
orage=19 or age=20如果 age 是 19 或者 20,则返回 true。如果 age 是其他值,则返回 false
andage>19 and age<21如果 age 大于 19 且小于 21,则返回 true。如果 age 是其他值,则返回 false
mod计算除法的余数5 mod 21
|计算两个节点集//book | //cd返回所有拥有 book 和 cd 元素的节点集
+加法10 + 515
-减法10 - 55
*乘法10 * 550
div除法10 div 52
=等于age=19如果 age 是 19,则返回 true。如果 age 不是 19,则返回 false
!=不等于age!=19如果 age 不是 19,则返回 true。如果 age 是 19,则返回 false
<小于age<19如果 age 小于 19,则返回 true。如果 age 不小于 19,则返回 false
<=小于或等于age<=19如果 age 小于等于 19,则返回 true。如果 age 大于 19,则返回 false
>大于age>19如果 age 大于 19,则返回 true。如果 age 不大于 19,则返回 false
>=大于或等于age>=19如果 age 大于等于 19,则返回 true。如果 age 小于 19,则返回 false

【7.11】按顺序选择节点

某些属性可能同时匹配了多个节点,如果要选择其中几个节点,可以利用中括号传入索引的方法获取特定次序的节点

from lxml import etreetext = '''
<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>
'''
html = etree.HTML(text)
result = html.xpath('//li[1]/a/text()')
print(result)
result = html.xpath('//li[last()]/a/text()')
print(result)
result = html.xpath('//li[position()<3]/a/text()')
print(result)
result = html.xpath('//li[last()-2]/a/text()')
print(result)
  • li[1]:选取第一个 li 节点;
  • li[last()]:选取最后一个 li 节点;
  • position()< 3:选取位置小于 3 的 li 节点;
  • li[last()-2]:选取倒数第三个 li 节点

输出结果:

['first item']
['fifth item']
['first item', 'second item']
['third item']

【7.12】节点轴选择

节点轴选择:获取子元素、兄弟元素、父元素、祖先元素等

from lxml import etreetext = '''
<div><ul><li class="item-0"><a href="link1.html"><span>first item</span></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>
'''
html = etree.HTML(text)
result = html.xpath('//li[1]/ancestor::*')
print(result)
result = html.xpath('//li[1]/ancestor::div')
print(result)
result = html.xpath('//li[1]/attribute::*')
print(result)
result = html.xpath('//li[1]/child::a[@href="link1.html"]')
print(result)
result = html.xpath('//li[1]/descendant::span')
print(result)
result = html.xpath('//li[1]/following::*[2]')
print(result)
result = html.xpath('//li[1]/following-sibling::*')
print(result)

输出结果:

[<Element html at 0x1d3749e9548>, <Element body at 0x1d3749e94c8>, <Element div at 0x1d3749e9488>, <Element ul at 0x1d3749e9588>]
[<Element div at 0x1d3749e9488>]
['item-0']
[<Element a at 0x1d3749e9588>]
[<Element span at 0x1d3749e9488>]
[<Element a at 0x1d3749e9588>]
[<Element li at 0x1d3749e94c8>, <Element li at 0x1d3749e95c8>, <Element li at 0x1d3749e9608>, <Element li at 0x1d3749e9648>]

基本语法:轴名称::节点测试[谓语]

轴名称对应的结果:

轴名称结果
ancestor选取当前节点的所有先辈(父、祖父等)
ancestor-or-self选取当前节点的所有先辈(父、祖父等)以及当前节点本身
attribute选取当前节点的所有属性
child选取当前节点的所有子元素
descendant选取当前节点的所有后代元素(子、孙等)
descendant-or-self选取当前节点的所有后代元素(子、孙等)以及当前节点本身
following选取文档中当前节点的结束标签之后的所有节点
namespace选取当前节点的所有命名空间节点
parent选取当前节点的父节点
preceding选取文档中当前节点的开始标签之前的所有节点
preceding-sibling选取当前节点之前的所有同级节点
self选取当前节点

实例:

例子结果
child::book选取所有属于当前节点的子元素的 book 节点
attribute::lang选取当前节点的 lang 属性
child:: *选取当前节点的所有子元素
attribute:: *选取当前节点的所有属性
child::text()选取当前节点的所有文本子节点
child::node()选取当前节点的所有子节点
descendant::book选取当前节点的所有 book 后代
ancestor::book选择当前节点的所有 book 先辈
ancestor-or-self::book选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点)
child:: */child::price选取当前节点的所有 price 孙节点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437947.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sharepoint学习笔记—error处理-- The user does not exist or is not unique.

看到网上不少人遇到过这种类似的错误&#xff0c;而产生这种错误的原因也有多种&#xff0c;我产生此错误的背景是在试图通过ECMAscript对象模型把一个User添加到某个指定的Group中时遇到的。 问题1.当我试图把一个User添加到Sharepoint的某个指定的Group&#xff0c;…

Python3 爬虫学习笔记 C08【解析库 Beautiful Soup】

Python3 爬虫学习笔记第八章 —— 【解析库 Beautiful Soup】文章目录【8.1】关于 Beautiful Soup【8.2】Beautiful Soup 的基本使用【8.3】节点选择器【8.3.1】元素选择【8.3.2】提取信息【8.3.3】嵌套选择【8.3.4】关联选择【8.4】方法选择器【8.4.1】find_all() 方法【8.4.2…

Sharepoint学习笔记—Ribbon系列

为便于查阅&#xff0c;这里整理并列出了我的Sharepoint学习笔记中涉及Ribbon开发的关文章&#xff0c;有些内容可能会在以后更新。 Sharepoint学习笔记—Ribbon系列-- 1. Ribbon的架构 Sharepoint学习笔记—Ribbon系列-- 2. 在Ribbon中添加新Tab Sharepoint学习笔记—Ribbo…

Python3 爬虫学习笔记 C09【数据储存系列 — 文件储存】

Python3 爬虫学习笔记第九章 —— 【数据储存系列 — 文件储存】文章目录【9.1】TXT 文本存储【9.1.1】基本示例【9.1.2】打开方式【9.2】JSON 文件存储【9.2.1】对象和数组【9.2.2】读取 JSON【9.2.3】写入 JSON 文件【9.3】CSV 文本存储【9.3.1】写入【9.3.2】读取用解析器解…

Knockout学习笔记之二($root,$parent及$data的区别)

以下是我从Google上找到的一个例子&#xff0c;非常生动形象&#xff0c;我修改了部分代码&#xff0c;具体内容如下&#xff1a; 对于$root 与$parent的区别&#xff1a; $root refers to the view model applied to the DOM with ko.applyBindings;译&#xff1a;$root 是指…

GitHub 学生认证,申请 GitHub 学生包

GitHub 面对学生推出了学生认证服务&#xff0c;通过认证后就可以得到学生包&#xff0c;学生包大概有十几项优惠&#xff0c;包括 DATADOG Pro 帐户、免费两年的10台服务器&#xff0c;Icons8 3个月的带图标&#xff0c;照片&#xff0c;插图和音乐订阅服务、JETBRAINS 专业桌…

Sharepoint学习笔记—架构系列

为便于查阅&#xff0c;这里整理并列出了我的Sharepoint学习笔记中涉及架构方面的有关文章&#xff0c;有些内容可能会在以后更新。 Sharepoin学习笔记—架构系列-- Sharepoint的网页(Page)&#xff0c;网页解析(Parsing)与解析安全处理(Security) Sharepoin学习笔记 —架构…

Python3 使用 pymysql 连接 MySQL 建表时出现 Warning3719 UTF8 警告

在学习 Python3 爬虫关系型数据库储存时&#xff0c;利用 pymysql 连接 MySQL 建表&#xff0c;测试用的代码如下&#xff0c;第一句 SQL 用于获取当前 MySQL 的版本信息&#xff0c;第二句 SQL 执行创建 spiders 数据库的操作&#xff0c;如果程序代码正确&#xff0c;将会输出…

Sharepoin学习笔记—架构系列--01 Sharepoint的网页(Page),网页解析(Parsing)与解析安全处理(Security)

Microsoft SharePoint Foundation 中主要有两种类型的页面&#xff0c;分别是应用程序页(Application Page) 和网站页(Site Page)。 应用程序页(Application Page) 和网站页(Site Page)都从同一母版页继承其布局。 应用程序页(Application Page)与传统的 Microsoft ASP.NET 3.5…

完美解决 bash: hexo: command not found

背景介绍&#xff1a;有好几天没动过 Hexo 博客了&#xff0c;今天准备更新的时候输入 hexo s&#xff0c;报错 bash: hexo: command not found&#xff0c;这是啥情况&#xff1f;以前都好好的&#xff0c;想了一下&#xff0c;大概是这几天折腾各种 Python 库的原因&#xff…

Sharepoin学习笔记 —架构系列--02 Sharepoint的处理(Process)与执行模型(Trust Model) 1

Sharepoint210有四种执行模型: 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法&#xff08;Hybrid Approach&#xff09; Sharepoint最简单的处理模型就是一个完整的Asp.net应…

Python3 爬虫学习笔记 C10【数据储存系列 — MySQL】

Python3 爬虫学习笔记第十章 —— 【数据储存系列 — MySQL】文章目录【10.1】MySQL 基本操作语句数据库操作表操作表的结构表的数据【10.2】Python 连接 MySQL【10.3】创建表【10.4】插入数据【10.5】更新数据【10.6】删除数据【10.7】查询数据【10.8】实战训练 — 爬取CSDN博…

Sharepoin学习笔记—架构系列--03 Sharepoint的处理(Process)与执行模型(Trust Model) 2

上文我们了解了一个外部Http Request进入IIS 工作进程(W3WP)的处理与执行信任模型&#xff0c;这个阶段是Sharepoint的四种执行模型都必须经过的处理阶段&#xff0c;其中Sharepoint场解决方案与任何 ASP.NET 应用程序一样就是在 IIS 工作进程(w3wp)中运行的&#xff0c;所以上…

Python3 爬虫学习笔记 C11【数据储存系列 — MongoDB】

Python3 爬虫学习笔记第十一章 —— 【数据储存系列 — MongoDB】文章目录【11.1】关于 MongoDB【11.2】MongoDB 基本操作语句【11.3】连接 MongoDB【11.4】指定数据库【11.5】指定集合【11.6】插入数据【11.6】数据查询【11.7】数据计数【11.8】数据排序【11.9】数据偏移【11.…

Sharepoin学习笔记—架构系列--04 Sharepoint的四种执行模型 1

Sharepoint210有四种执行模型 1、完全信任执行模型(Full Trust) 2、Bin/CAS 执行模型 &#xff08;1与2都属于场解决方案&#xff09; 3、沙盒执行模型(Sand Box) 4、 混合执行方法 (Hybrid Approach) 下面分别来看看它们是怎么回事 一、场解决方案 场解决方案是在 Share…

Python3 爬虫学习笔记 C12【验证码对抗系列 — 图形验证码】

Python3 爬虫学习笔记第十二章 —— 【验证码对抗系列 — 图形验证码】文章目录【12.1】关于普通图形验证码【12.2】tesserocr 库识别验证码【12.3】pytesseract 库识别验证码【12.4】验证码处理【12.5】tesserocr 与 pytesserocr 相关资料【12.1】关于普通图形验证码 普通图形…

Sharepoin学习笔记—架构系列--05 Sharepoint的四种执行模型 2

上一篇我们看了场解决方案与沙盒方案两种执行模型&#xff0c;其中场解决方案包括有完全信任方式与Bin/CAS方式两种&#xff0c;这里让我们继续来看看最后一个执行模型&#xff0c;即混合模型(或混合模式)。 三、混合模式&#xff08;hybrid approaches&#xff09; 所谓混合模…

Python3 爬虫学习笔记 C13【验证码对抗系列 — 滑动验证码】

Python3 爬虫学习笔记第十三章 —— 【验证码对抗系列 — 滑动验证码】文章目录【13.1】关于滑动验证码【13.2】滑动验证码攻克思路【13.3】模拟登录 bilibili — 总体思路【13.4】主函数【13.5】初始化函数【13.6】登录函数【13.7】验证码元素查找函数【13.8】元素可见性设置函…

Sharepoin学习笔记—架构系列—06 Sharepoint服务(Services)与服务应用程序框架(Service Application Framework) 1

Sharepoint服务是Sharepoint的重要组成&#xff0c;可以说Sharepoint的许多网站功能都是基于这些服务构架起来的。这里把Sharepoint服务的相关要点总结一下。 1、什么是 SharePoint 服务&#xff1f; SharePoint 服务是一项 IT 服务&#xff0c;它是运行在后台&#xff0c;为调…

Python3 爬虫学习笔记 C14【验证码对抗系列 — 点触验证码】

Python3 爬虫学习笔记第十四章 —— 【验证码对抗系列 — 点触验证码】文章目录【14.1】关于点触验证码【14.2】点触验证码攻克思路【14.3】模拟登录 12306 — 总体思路【14.4】主函数【14.5】初始化函数【14.6】破解入口函数【14.7】账号密码输入函数【14.8】页面截图函数【14…