当前位置: 首页 > news >正文

Python 使用 XPath 查找元素基本用法实战指南

前言

在爬虫、网页数据提取场景中,解析HTML常用两种方案:CSS选择器、XPath。
XPath 功能更强大,支持父子层级、属性模糊匹配、文本匹配、多条件筛选,是 Python 爬虫主流解析方式。
很多同学刚开始使用 XPath 经常遇到路径写错、找不到元素、匹配规则失效等问题。
本文基于lxml(最常用库)讲解 XPath 在 Python 中的基础语法、常用案例、避坑要点,所有代码可直接运行。

说明:本文使用XPath 1.0,lxml 仅支持 XPath 1.0,部分 XPath2.0 函数无法使用。

一、环境准备

安装依赖

pip install lxml

基础载入模板

from lxml import etree html = """ <html> <body> <div id="box"> <h2 class="title">Python XPath教程</h2> <div class="item">文章1</div> <div class="item">文章2</div> <div id="c_001">ID以c开头的区块</div> <div id="d_001">普通区块</div> <a href="https://www.baidu.com">百度</a> </div> </body> </html> """ # 构建解析对象 tree = etree.HTML(html)

二、绝对路径 vs 相对路径

1. 绝对路径(不推荐)

从根节点一层层往下写,结构一旦变动直接失效。

# 查找h2文本 res = tree.xpath('/html/body/div/h2/text()') print(res)

2. 相对路径(日常开发首选)

  • //标签名:全局搜索,任意位置查找该标签
  • .//标签名在当前节点内部搜索(重点!)
# 全局查找所有h2 res = tree.xpath('//h2/text()') # 先拿到box节点,再在box内部查找所有div box_node = tree.xpath('//div[@id="box"]')[0] items = box_node.xpath('.//div/text()') print(items)

⚠️ 高频踩坑:在节点对象上调用xpath,如果不加.//依旧会全局搜索,不会限定在当前节点!

三、获取文本、属性、节点对象

1./text()获取标签内直接文本

# 获取h2内部文本 title = tree.xpath('//h2/text()')[0] print(title)

2.@属性名获取属性值

# 获取a标签href链接 href = tree.xpath('//a/@href')[0] print(href)

3. 不使用/text(),直接获取元素对象

想要打印元素完整HTML源码时,必须拿到节点对象,不能提取文本

h2_node = tree.xpath('//h2')[0] # 输出完整标签HTML html_str = etree.tostring(h2_node, encoding="utf-8").decode("utf-8") print(html_str)

四、属性筛选语法(最常用)

4.1 属性精确匹配

//div[@id="box"] //h2[@class="title"]

python示例:

node = tree.xpath('//div[@id="box"]')

坑点:class 内存在多余空格时,精确匹配会失败!例如class="element-header "

4.2 模糊匹配(三大核心函数)

lxml支持XPath1.0内置三个函数:

  1. starts-with(@属性, "开头字符")属性以指定内容开头
# 查找id以c开头的div c_divs = tree.xpath('//div[starts-with(@id, "c")]')
  1. contains(@属性, "关键词")属性包含关键词
# class包含item的div item_divs = tree.xpath('//div[contains(@class, "item")]')
  1. ends-with()不支持!属于XPath2.0,lxml无法使用。

4.3 多条件组合and / or

# class=item 并且文本包含文章 res = tree.xpath('//div[@class="item" and contains(text(), "文章")]/text()')

五、层级关系筛选

  1. /直接子节点
//div[@id="box"]/h2

只匹配box下直接子元素h2,孙子层级不会匹配

  1. //后代所有节点(子、孙、曾孙)
//div[@id="box"]//div
  1. 匹配第N个元素[position()]
# 第一个class为item的div first_item = tree.xpath('//div[@class="item"][1]/text()') # 最后一个 last_item = tree.xpath('//div[@class="item"][last()]/text()')

六、文本匹配技巧

匹配标签内文本

# 文本完全等于 res = tree.xpath('//h2[text()="Python XPath教程"]/text()') # 文本包含关键词 res = tree.xpath('//h2[contains(text(), "XPath")]/text()')

注意:标签存在换行、空格时,text()精确匹配容易失败,优先使用contains

七、实战通用模板

模板1:在指定节点内部循环提取元素

# 拿到父节点 box = tree.xpath('//div[@id="box"]')[0] # 在父节点内查找所有item item_list = box.xpath('.//div[@class="item"]') for item in item_list: text = item.xpath('./text()')[0] print(text)

模板2:获取元素完整HTML

def get_html(elem): return etree.tostring(elem, encoding="utf-8").decode("utf-8") item_node = tree.xpath('//div[@class="item"][0]')[0] print(get_html(item_node))

八、高频踩坑清单

  1. 在节点对象使用xpath忘记加.
    box.xpath('//div')全局搜索,box.xpath('.//div')才是内部搜索
  2. class带有多余空格,直接使用@class="xxx"精确匹配失败,改用contains
  3. 想打印HTML,却写了/text(),拿到字符串而不是元素对象
  4. 混淆///,需要后代却只写直接子节点/
  5. 试图使用ends-with()lower-case()函数,lxml不支持XPath2.0
  6. xpath匹配结果为空列表,直接[0]取值触发报错
    建议增加判断:
result = tree.xpath('//h2/text()') if result: print(result[0])

九、补充:Selenium / DrissionPage 兼容说明

如果你使用 DrissionPage、Selenium,XPath语法完全通用

# DrissionPage示例 items = page.xpath('.//div[starts-with(@id,"c")]')

区别:selenium获取文本使用.text属性,不再依赖/text()

总结

  1. .//xxx限定当前节点内部查找,//xxx全局查找;
  2. 精确匹配用@属性="值",模糊匹配优先starts-withcontains
  3. 需要HTML源码就不要加/text(),保留元素对象;
  4. 优先使用相对路径,避免脆弱的绝对路径;
  5. lxml只支持XPath1.0,不要使用XPath2.0专属函数。

掌握以上基础用法,可以覆盖80%网页数据提取场景。复杂爬虫筛选需求,都可以在这套基础语法上进行组合扩展。

http://www.jsqmd.com/news/1392764/

相关文章:

  • 小白程序员必看!收藏这份中国工业AI规模化应用指南,轻松入门大模型时代
  • 2026海南增值税发票增版增量代办**机构推荐|企业发票额度不够怎么办?发票限额调整完整操作指南+线下实地核查全流程 - 米諾
  • 产品经理的AI工具箱,奇点大会的实操清单整理
  • 从折腾一整天到 30 分钟收工:OpCore-Simplify 一键生成 OpenCore EFI 的完整指南
  • 人均五千够不够川藏318自驾玩一趟2026年 - 老金2026
  • 有没有好用的JMeter替代工具?五款热门工具对比
  • 用aardio获取网络上的图片存到本地
  • AI中转站掺水篡改实测排查实战:19家平台数据+检测脚本+避坑方案
  • 奇点大会的因果图模型实践,对业务分析人员有什么用
  • 【AI】Agent 全栈进阶|大模型基础与对话调用
  • 2026年8月百色屋顶漏水维修哪家好?正规防水修缮科普指南 - 聪居到家
  • 一站式B站视频下载工具BiliTools:跨平台免费,5分钟快速上手
  • Visual C++ 运行库报错不用慌:AIO 工具一行命令装齐 6 大版本
  • 2026长沙公司注销最全避坑指南!别盲目走简易注销,90%老板都踩雷 - 小征每日分享
  • 奇点智能大会参会指南,哪些场次值得优先占位
  • 领创单招招生学校电话在哪里查?各校区**联系方式看这里 - 官方资讯
  • 微信小游戏兼容性测试怎么做?从机型分层到核心链路验证
  • Python如何使用XPath定位没有特征的元素?无id、无class通用定位技巧
  • 2026年进贤县监控安防,本地优质服务商参考 - 官方资讯
  • 储能行业如何打通海外获客渠道?储能海外营销代运营服务商助力B2B海外获客与品牌推广(附带联系方式) - 选型|行业|价格|案例
  • 太原见|易基因科技与您相约2026年度染色质生物学与表观遗传学大会
  • 零剪辑基础也能做:Pixelle-Video帮你10分钟自动生成一条AI短视频
  • 2026贵阳装修设计公司推荐:贵阳绿豆家多维详解 - 深度智识库
  • 猫抓资源嗅探扩展使用路线图:3个成长阶段,把网页视频音频图片全拿下
  • 信号详细讲解
  • 8月到新疆旅游报团价格是多少?新疆旅游团10天9晚价格参考,亲子游纯玩团无购物无隐形消费放心出行 - 跟我去旅游
  • Windows 11 越来越卡?Win11Debloat 一键系统优化与隐私清理终极指南
  • 圈内流传 CTF 完整版入门教程,零基础直达竞赛,错过很难再找到
  • 关于docker的使用心得
  • scrcpy投屏实战指南:不用root,5分钟让电脑接管你的安卓手机