本课程共五个章节,课程地址:
【Python爬虫教程】花9888买的Python爬虫全套教程2021完整版现分享给大家!(已更新项目)——附赠课程与资料_哔哩哔哩_bilibili
第二章
- 数据解析概述
- 正则表达式
- re模块
- 手刃豆瓣TOP250电影信息
- bs4解析-HTML语法
- bs4解析-bs4模块安装和使用
- 抓取让你睡不着觉的图片
- xpath解析
- 抓取猪八戒数据
目录
(八)xpath解析
xpath 是一门在 XML 文档中查找信息的语言,可用来在 XML 文档中对元素和属性进行遍历。而我们熟知的 HTML 恰巧属于 XML 的一个子集,所以完全可以用 xpath 去查找 html 中的内容。xpath 比 re 和 bs4 既简单又高效
<book>
<id>1</id>
<name>野花遍地香</name>
<price>1.23</price>
<author>
<nick>周大强</nick>
<nick>周芷若</nick>
</author>
</book>
# xpath的语法规则:靠着节点之间的关系去查找,如:/book/price;也可以通过属性来查找,如bs4
在上述 html 中:
- book、id、name、price... 都被称为节点
- id、name、price、author 被称为 book 的子节点
- book 被称为 id、name、price、author 的父节点
- id、name、price、author 被称为同胞节点
用 xpath解析 就可以用节点之间的关系来去查找某个节点
在python中想要使用xpath,需要安装lxml模块
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple lxml
用法:
- 将要解析的html内容构造出etree对象
- 使用etree对象的xpath()方法,配合xpath表达式来完成对数据的提取
案例一:
# xpath解析
from lxml import etree # etree里包含了xpath的功能 etree.XML().xpath()
xml = """
<book>
<id>1</id>
<name>野花遍地香</name>
<price>1.23</price>
<nick>臭豆腐</nick>
<author>
<nick id="10086">周大强</nick>
<nick id="10010">周芷若</nick>
<nick class="joy">周杰伦</nick>
<nick class="jolin">蔡依林</nick>
<div>
<nick>热1</nick>
</div>
<span>
<nick>热2</nick>
</span>
</author>
<partner>
<nick id="ppc">胖胖陈</nick>
<nick id="ppbc">胖胖不陈</nick>
</partner>
</book>
"""
tree = etree.XML(xml) # 把内容加载为etree对象
result = tree.xpath("/book") # /表示层级关系. 第一个/是根节点 [<Element book at 0x2a08bf79200>]
result = tree.xpath("/book/name") # [<Element name at 0x1fb7cf29740>]
result = tree.xpath("/book/name/text()") # text() 拿文本 ['野花遍地香']
result = tree.xpath("/book/author//nick/text()") # // 所有后代 ['周大强', '周芷若', '周杰伦', '蔡依林', '热1', '热2']
# 热1为 author/div/nick 热2为 author/span/nick
result = tree.xpath("/book/author/*/nick/text()") # * 任意的节点. 通配符 ['热1', '热2']
# 拿所有nick
result = tree.xpath("/book//nick/text()") # ['臭豆腐', '周大强', '周芷若', '周杰伦', '蔡依林', '热1', '热2', '胖胖陈', '胖胖不陈']
print(result)
案例二:
先看提前准备好的一个网页(b.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<ul>
<li><a href="http://www.baidu.com">百度</a></li>
<li><a href="http://www.google.com">谷歌</a></li>
<li><a href="http://www.sogou.com">搜狗</a></li>
</ul>
<ol>
<li><a href="feiji">飞机</a></li>
<li><a href="dapao">大炮</a></li>
<li><a href="huoche">火车</a></li>
</ol>
<div class="job">李嘉诚</div>
<div class="common">胡辣汤</div>
</body>
</html>
xpath如何提取属性信息?三个重要的点:
局部解析:./
属性选取:[@class='xxx']
获取文本:text()
查找:
from lxml import etree
tree = etree.parse("b.html") # .parse() 加载文件
# ['百度', '谷歌', '搜狗']
result = tree.xpath("/html/body/ul/li/a/text()")
# ['百度']
result = tree.xpath("/html/body/ul/li[1]/a/text()") # xpath的顺序是从1开始数的, []表示索引
# ['大炮']
result = tree.xpath("/html/body/ol/li/a[@href='dapao']/text()") # [@xxx=xxx] 属性的筛选
print(result)
遍历:
ol_li_list = tree.xpath("/html/body/ol/li")
for li in ol_li_list:
# 从每一个li中提取到文字信息
result = li.xpath("./a/text()") # 局部解析 在li中继续去寻找. 相对查找 ./表示当前节点,即li
print(result)
result2 = li.xpath("./a/@href") # 拿到属性值: @属性
print(result2)
拿属性值:
print(tree.xpath("/html/body/ul/li/a/@href"))
小技巧:
但是当网页源代码极其复杂时,不易看出结构,此时有一个小技巧
在网页按 f12,查看 Elements,如下:
# ['李嘉诚']
print(tree.xpath('/html/body/div[1]/text()'))
# ['大炮']
print(tree.xpath('/html/body/ol/li[2]/a/text()'))
# ['飞机', '大炮', '火车']
print(tree.xpath('/html/body/ol/li/a/text()')) # 做个微调