Python xpath 主要是配合 lxml 库或者 scrapy 框架,通过 xpath 表达式从 html xml 文档里面精准查找节点,xpath 本质是路径表达式,按照文档树结构定位标签 属性 文本内容,爬虫开发里面使用频率很高,很多新手写 python xpath 的时候,经常路径写错,相对路径绝对路径混淆,还分不清 text 和 @属性取值,编写的时候第一步导入 lxml 解析模块,第二步把 html 源码转成 Element 对象,第三步编写 xpath 定位表达式,第四步调用 xpath 方法执行查询,第五步提取文本或者属性值,第六步处理空结果和动态页面异常,掌握 python xpath 之后,可以灵活定位列表 表格 链接,是爬虫解析页面核心技能。
一 pythonxpath 基础环境准备
python xpath 常用库是 lxml,安装命令 pip install lxml
导入代码
from lxml import etree
核心流程
原始 html 字符串 转成 etree.HTML 解析对象 执行 xpath 查询
注意 如果是 scrapy 项目,response 对象自带 xpath 方法,不需要单独导入 lxml,写法是 response.xpath 表达式
二 xpath 基础路径语法
| 语法 | 含义 |
|---|---|
| / | 从根节点开始,绝对路径 |
| // | 跨层级查找,任意位置匹配节点 |
| . | 当前节点 |
| .. | 父节点 |
| @ | 选取属性 |
| text | 选取节点内部文本 |
| [] | 条件筛选 |
基础示例
html = etree.HTML (html 源码)
result = html.xpath ("//div")
查找页面所有 div 标签
三 条件筛选深度用法
1 属性匹配 标签名 [@属性名 = 属性值]
示例 //a [@class=link]
查找 class 等于 link 的 a 标签
2 多条件 同时满足多个属性
//div [@id=box and @class=item]
3 文本筛选 按照标签内文字匹配
//li [text ()= 标题文字]
4 位置筛选 下标从 1 开始,这点非常关键,xpath 下标不是从 0 开始
//li [1] 第一个 li
//li [last ()] 最后一个 li
//li [position ()>2] 第三个之后所有 li
四 提取文本与属性
1 提取标签内部文本
//div/text () 取出直接子文本
//div//text () 取出 div 内部所有层级全部文本,包含子标签里面文字
2 提取属性值
//a/@href 取出所有 a 标签 href 链接
五 深度技术要点
1 python xpath 返回结果默认是列表,就算只匹配到一个节点,返回依然是列表,取值的时候要注意下标,很多新手直接当成单个对象报错
2 相对路径写法,在已经定位到节点之后,继续使用./ 代表当前节点,不要每次都重新写 //,否则会重新从整个 html 根节点搜索,造成结果错误
3 中文匹配的时候,页面编码要统一,编码错乱会导致 python xpath 文本条件匹配失败
4 动态 js 渲染页面,原始 html 源码里面没有目标节点,单纯 python xpath 查询不到,这种场景需要 selenium 获取渲染之后页面源码再解析
5 xpath 支持轴节点,preceding-sibling preceding following-sibling,用来查找同级前后兄弟节点,处理复杂表格非常实用
6 模糊匹配 contains,适合 class 多个值的情况,//div [contains (@class,item)],只要 class 里面包含 item 就可以匹配,比精确等于更适合爬虫
六 完整实操步骤清单
1 安装 lxml 库
2 获取网页 html 源码
3 使用 etree.HTML 把源码解析成节点树
4 编写 xpath 表达式,优先使用 // 跨层级查找
5 调用.xpath 执行查询,得到节点列表
6 对节点提取 text 或者 @属性
7 检查返回列表是否为空,判断页面是否改版或者路径失效
8 项目长期运行,xpath 路径失效要及时更新表达式
【常见问题】
问题 1 pythonxpath 返回为什么是列表
回答 1 pythonxpath 执行查询默认返回匹配节点组成的列表,pythonxpath 就算只匹配到单个元素,结果依旧是列表,取值需要增加下标读取元素
问题 2 pythonxpath 下标为什么是从 1 开始
回答 1 pythonxpath 语法规则下标起始是 1,pythonxpath 和 python 列表从 0 开始不一样,写 pythonxpath 位置筛选的时候不要写成 0,否则取不到节点
问题 3 pythonxpath 找不到节点是什么原因
回答 1 pythonxpath 找不到节点常见原因是路径写错,或者页面是 js 动态渲染原始源码没有节点,pythonxpath 只可以解析已经存在 html 树里面的节点,动态内容需要先获取渲染后的源码
问题 4 pythonxpath 里面 contains 是做什么的
回答 1 pythonxpath 里面 contains 用于模糊属性匹配,pythonxpath 适合 class 多值这种场景,不需要属性完全相等,只要属性里面包含指定字符就可以匹配成功
【免责申明】
本文 pythonxpath 相关内容基于 lxml 和 scrapy 标准语法编写,网站页面结构改版会导致 xpath 定位失效,爬虫开发请遵守目标网站 robots 协议与相关法律法规,本内容仅作技术参考,不对业务运行异常承担责任。


