ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

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

Python 使用 XPath 查找元素基本用法实战指南 前言在爬虫、网页数据提取场景中解析HTML常用两种方案CSS选择器、XPath。XPath 功能更强大支持父子层级、属性模糊匹配、文本匹配、多条件筛选是 Python 爬虫主流解析方式。很多同学刚开始使用 XPath 经常遇到路径写错、找不到元素、匹配规则失效等问题。本文基于lxml最常用库讲解 XPath 在 Python 中的基础语法、常用案例、避坑要点所有代码可直接运行。说明本文使用XPath 1.0lxml 仅支持 XPath 1.0部分 XPath2.0 函数无法使用。一、环境准备安装依赖pip install lxml基础载入模板from lxml import etree html html body div idbox h2 classtitlePython XPath教程/h2 div classitem文章1/div div classitem文章2/div div idc_001ID以c开头的区块/div div idd_001普通区块/div a hrefhttps://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[idbox])[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, encodingutf-8).decode(utf-8) print(html_str)四、属性筛选语法最常用4.1 属性精确匹配//div[idbox] //h2[classtitle]python示例node tree.xpath(//div[idbox])坑点class 内存在多余空格时精确匹配会失败例如classelement-header 4.2 模糊匹配三大核心函数lxml支持XPath1.0内置三个函数starts-with(属性, 开头字符)属性以指定内容开头# 查找id以c开头的div c_divs tree.xpath(//div[starts-with(id, c)])contains(属性, 关键词)属性包含关键词# class包含item的div item_divs tree.xpath(//div[contains(class, item)])ends-with()不支持属于XPath2.0lxml无法使用。4.3 多条件组合and / or# classitem 并且文本包含文章 res tree.xpath(//div[classitem and contains(text(), 文章)]/text())五、层级关系筛选/直接子节点//div[idbox]/h2只匹配box下直接子元素h2孙子层级不会匹配//后代所有节点子、孙、曾孙//div[idbox]//div匹配第N个元素[position()]# 第一个class为item的div first_item tree.xpath(//div[classitem][1]/text()) # 最后一个 last_item tree.xpath(//div[classitem][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[idbox])[0] # 在父节点内查找所有item item_list box.xpath(.//div[classitem]) for item in item_list: text item.xpath(./text())[0] print(text)模板2获取元素完整HTMLdef get_html(elem): return etree.tostring(elem, encodingutf-8).decode(utf-8) item_node tree.xpath(//div[classitem][0])[0] print(get_html(item_node))八、高频踩坑清单在节点对象使用xpath忘记加.box.xpath(//div)全局搜索box.xpath(.//div)才是内部搜索class带有多余空格直接使用classxxx精确匹配失败改用contains想打印HTML却写了/text()拿到字符串而不是元素对象混淆/和//需要后代却只写直接子节点/试图使用ends-with()、lower-case()函数lxml不支持XPath2.0xpath匹配结果为空列表直接[0]取值触发报错建议增加判断result tree.xpath(//h2/text()) if result: print(result[0])九、补充Selenium / DrissionPage 兼容说明如果你使用 DrissionPage、SeleniumXPath语法完全通用# DrissionPage示例 items page.xpath(.//div[starts-with(id,c)])区别selenium获取文本使用.text属性不再依赖/text()。总结.//xxx限定当前节点内部查找//xxx全局查找精确匹配用属性值模糊匹配优先starts-with、contains需要HTML源码就不要加/text()保留元素对象优先使用相对路径避免脆弱的绝对路径lxml只支持XPath1.0不要使用XPath2.0专属函数。掌握以上基础用法可以覆盖80%网页数据提取场景。复杂爬虫筛选需求都可以在这套基础语法上进行组合扩展。
返回列表