【python爬虫】xpath使用说明

XPath 可以在XML文档中查找信息,支持HTML,可以用来提取信息。可以把标签文本看作一个树状图,最顶层是html,第二层是head和body,body的下面是许多div,每个div可以用/[@属性=属性名]来进一步细分,也可以通过/@属性来获取对应的信息,提取双标签中的文字则可以用/text()。

安装库

sh 复制代码
pip3 install lxml

基本使用

python 复制代码
from lxml import etree  
wb_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">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(wb_data)  
print(html)  
result = etree.tostring(html)  
print(result.decode("utf-8"))

从下面的结果来看,这里的html其实就是一个python对象,etree.tostring(html)则补全了html缺胳膊少腿的标签。

输出结果:

python 复制代码
<Element html at 0x39e58f0>  
<html><body><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>  
    </body></html>

语法

选取节点

XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。

下面列出了最有用的路径表达式:

表达式 描述
nodename 选取此节点的所有子节点。
/ 表示子级范围
// 表示子孙后代范围
. 选取当前节点。
... 选取当前节点的父节点。
@ 根据属性具体判断某一个标签,可以通过 标签名属性值判断式 来定位,

示例

在下面的表格中,我们已列出了一些路径表达式以及表达式的结果:

路径表达式 结果
bookstore 选取 bookstore 元素的所有子节点。
/bookstore 选取元素 bookstore。注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
bookstore/book 选取属于 bookstore 的子元素的所有 book 元素。
//book 选取所有 book 子元素,而不管它们在文档中的位置。
bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。
//@lang 选取名为 lang 的所有属性。

谓语(Predicates)

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

顺序定位

  1. 方式一:1
    通配标签返回的是一个列表,里面为空或者一些元素。
    xpath支持取具体值, 例如去列表的第一个元素,1就可以拿到;第二个值就是2
    注意列表的下角标从1开始,不像python那样从0开始
  2. 方式二:position()
    position函数会返回当前的位置值,拿到值之后就可以对值进行判断选取。
    举例: 选取当前位置下的所有div标签,然后去掉第一个,取出从2开始,一直到最后 一个div标签。
    .//div[position()>1]
  3. 方式三:last()
    这个是最简单的,就是取列表的最后一个元素
    举例:
    .//div[last()]

示例

在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式 结果
/bookstore/book1 选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/booklast() 选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/booklast()-1 选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/bookposition() \< 3 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title@lang 选取所有拥有名为 lang 的属性的 title 元素。
//title@lang='eng' 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/bookprice\>35.00 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/bookprice\>35.00/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。

选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符 描述
* 匹配任何元素节点。
@* 匹配任何属性节点。
node() 匹配任何类型的节点。

示例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
/bookstore/* 选取 bookstore 元素的所有子元素。
//* 选取文档中的所有元素。
//title@\* 选取所有带有属性的 title 元素。

选取若干路径

通过在路径表达式中使用"|"运算符,您可以选取若干个路径。

示例

在下面的表格中,我们列出了一些路径表达式,以及这些表达式的结果:

路径表达式 结果
//book/title | //book/price 选取 book 元素的所有 title 和 price 元素。
//title | //price 选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。

与或非

通过与或非进行更严格的筛选

逻辑
关键字 and or not()
示例 .//div@id and @class .//div@id or @class .//divnot(@id)
示例解释 同时拥有id和class属性的div 有id或者class属性的div 没有id属性的 div

常用函数

contains(属性名,值)

匹配包含对应值的标签或数据

python 复制代码
response.xpath('//a[contains(text(),"Next >")]')
response.xpath('.//div[contains(@class,"content")]')

获取某个标签的内容(基本使用),注意,获取a标签的所有内容,a后面就不用再加正斜杠,否则报错。

text()

获取文本
写法一

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a')
print(html)
for i in html_data:
	print(i.text)

输出:

python 复制代码
<Element html at 0x12fe4b8>
first item
second item
third item
fourth item
fifth item

写法二

直接在需要查找内容的标签后面加一个/text()就行

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/text()')
print(html)
for i in html_data:
	print(i)

输出:

复制代码
<Element html at 0x138e4b8>
first item
second item
third item
fourth item
fifth item

parse(html文件路径)

打开读取html文件

python 复制代码
#使用parse打开html的文件
html = etree.parse('test.html')
html_data = html.xpath('//*')#打印是一个列表,需要遍历
print(html_data)
for i in html_data:
	print(i.text)

将文本转码

python 复制代码
html = etree.parse('test.html')
html_data = etree.tostring(html,pretty_print=True)
res = html_data.decode('utf-8')
print(res)

示例

打印指定路径下a标签的属性

可以通过遍历拿到某个属性的值,查找标签的内容

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('/html/body/div/ul/li/a/@href')
for i in html_data:
	print(i)

相对路径匹配

下面我们查找相对路径,例如,查找所有li标签下的a标签内容。

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('//li/a/text()')
print(html_data)
for i in html_data:
	print(i)

打印:

python 复制代码
['first item', 'second item', 'third item', 'fourth item', 'fifth item']
first item
second item
third item
fourth item
fifth item

使用相对路径,查找一下相对路径下li标签下的a标签下的href属性的值,注意,a标签后面需要双//。

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('//li/a//@href')
print(html_data)
for i in html_data:
	print(i)

打印:

python 复制代码
['link1.html', 'link2.html', 'link3.html', 'link4.html', 'link5.html']
link1.html
link2.html
link3.html
link4.html
link5.html

相对路径下跟绝对路径下查特定属性的方法类似,也可以说相同。

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('//li/a[@href="link2.html"]')
print(html_data)
for i in html_data:
	print(i.text)

打印:

python 复制代码
[<Element a at 0x216e468>]
second item

查找最后一个li标签里的a标签的href属性

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('//li[last()]/a/text()')
print(html_data)
for i in html_data:
	print(i)

打印:

python 复制代码
['fifth item']
fifth item

查找倒数第二个li标签里的a标签的href属性

python 复制代码
html = etree.HTML(wb_data)
html_data = html.xpath('//li[last()-1]/a/text()')
print(html_data)
for i in html_data:
	print(i)

打印:

python 复制代码
['fourth item']
fourth item
相关推荐
Scott9999HH2 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
二十雨辰4 小时前
[爬虫]-Urllib
爬虫·python
玉鸯6 小时前
Agent Hook:在概率推理之上,为 Agent 叠加确定性控制
python·langchain·agent
weixin_446260856 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
我的xiaodoujiao7 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
qetfw7 小时前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
用户8356290780518 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
一次旅行8 小时前
Python+大模型端到端自动化日报系统
开发语言·python·自动化