python xpath模块
xpath模块是一个可以提取XML代码的python工具,由于html代码是XML的子集,因此xpath也可以用于提取html代码。
下面分三步介绍xpath模块:
① 先介绍XML代码的概念
② 再介绍xpath是如何提取XML代码的
③ 最后介绍xpath是如何提取html代码的
一、XML代码介绍
<book>
<id>1</id>
<name>野花遍地⾹</name>
<price>1.23</price>
<author>
<nick>周⼤强</nick>
<nick>周芷若</nick>
</author>
</book>
在XML代码中,所有的标签被称为节点,上述XML代码中,最外层的book节点被称为根节点,内部的id,name,price,author节点均为book根节点的子节点,而author节点内部的nick节点是author的子节点,book的孙节点,id,name,price,author相互为同胞兄弟节点。
二、使用xpath模块提取XML代码
"""
1. 导入etree模块
2. 用xml字符串初始化etree对象
3. 使用xpath来匹配要寻找的节点内容
"""
from lxml import etree # 1. 导入etree模块
# 如果报错,考虑这种导入方式
# from lxml import html
# etree = html.etree
xml = """
<book>
<id>1</id>
<name>野花遍地⾹</name>
<price>1.23</price>
<nick>臭⾖腐</nick>
<author>
<nick id="10086">周⼤强</nick>
<nick id="10010">周芷若</nick>
<nick class="jay">周杰伦</nick>
<nick class="jolin">蔡依林</nick>
<div>
<nick>惹了</nick>
</div>
</author>
<partner>
<nick id="ppc">胖胖陈</nick>
<nick id="ppbc">胖胖不陈</nick>
</partner>
</book>
"""
et = etree.XML(xml) # 2. 用xml字符串初始化etree对象
# 3. 使用xpath来匹配要寻找的节点内容
result = et.xpath("/book") # 第一个'/'表示获取book根节点
result = et.xpath("/book/name") # 中间的'/'表示获取book名为name的儿子节点
result = et.xpath("/book/name/text()")[0] # 末尾节点后加 /text() 表示获取name节点的文本
result = et.xpath("/book//nick") # // 表示获取book子孙后代所有的nick标签
result = et.xpath("/book/*/nick/text()") # * 通配符可以匹配该级别下的任意节点,这里表示获取book节点的名为nick孙节点的文本
result = et.xpath("/book/author/nick[@class='jay']/text()") # []表示属性筛选,@属性名='值',相当于bs4中的find(nick, attr={"class": "jay"})
result = et.xpath("/book/partner/nick/@id") # 末尾节点后面的,/@属性名,表示获取标签的属性值,相当于bs4中的.get("id")
print(result)
三、使用xpath模块提取html代码
"""
1. 导入etree模块
2. 用html字符串初始化etree对象
3. 使用xpath来匹配要寻找的标签内容
"""
from lxml import etree # 1. 导入etree模块
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>
"""
et = etree.HTML(html) # 2. 用html字符串初始化etree对象
# 3. 使用xpath来匹配要寻找的标签内容
li_list = et.xpath("/html/body/ul/li[2]/a/text()") # 可以直接在路径里直接选取列表中的某一个标签
print(li_list)
li_list = et.xpath("//li")
for li in li_list:
href = li.xpath("./a/@href")[0] # ./ 表示当前节点
text = li.xpath("./a/text()")[0] # ./ 表示当前节点
print(href, text)
总结:
"""
xpath匹配的过程中,和Linux系统中的路径匹配十分相似。
寻找文本:/text()
寻找属性值:/@href
寻找某个属性值的标签:标签[@属性="值"]
寻找某个节点下所有子孙后带的标签:某个节点//标签
寻找某个节点下所有孙节点的标签:某个节点/*/标签
xpath的获取到的节点列表的下表索引从1开始计数
xpath可以直接在路径里通过[num]直接选取列表中的某一个标签
"""