
前言爬虫开发中经常遇到一类棘手场景目标元素没有id、没有class、没有独特属性无法直接通过属性筛选。div div标题/div div需要抓取的内容/div div备注信息/div /div如上代码所有标签完全一致没有任何特征属性。很多人第一反应只能靠页面顺序硬写路径页面微调一行代码爬虫直接失效。本文基于lxmlXPath1.0整理一套无特征元素定位方案包含层级索引、轴定位、相邻节点匹配、文本锚点等实战技巧适用于静态网页解析同时兼容Selenium、DrissionPage。前置说明lxml 仅支持 XPath 1.0下文所有语法全部兼容 lxml。一、环境基础模板from lxml import etree html div classcontainer div文章名称/div divPython XPath实战/div div发布时间/div div2026-08-14/div div内容摘要/div div无特征元素定位教程/div /div tree etree.HTML(html)二、方案1位置索引定位最简单慎用基础语法[n]代表同级第n个元素XPath下标从1开始不是0//div[classcontainer]/div[2]Python代码# 获取容器下第二个div target tree.xpath(//div[classcontainer]/div[2]/text()) print(target)⚠️ 缺点页面新增、删除任意同级标签顺序发生变化定位直接失效。适合静态页面、结构永远不会变动的场景不推荐作为首选方案。拓展用法[last()]匹配同级最后一个元素//div[classcontainer]/div[last()]position()3筛选位置大于3的元素//div[classcontainer]/div[position()3]三、方案2锚点文本定位最推荐业务首选核心思路找到旁边有固定文本的元素作为锚点再通过轴找到目标元素。示例需求已知文本文章名称抓取紧跟其后的Python XPath实战。1. following-sibling:: 后续同级元素匹配当前节点后面同级兄弟标签//div[text()文章名称]/following-sibling::div[1]Python示例res tree.xpath(//div[text()文章名称]/following-sibling::div[1]/text()) print(res) # [Python XPath实战]2. preceding-sibling:: 前面同级元素匹配当前节点前面同级兄弟标签//div[text()2026-08-14]/preceding-sibling::div[1]3. 兼容文本空格、换行问题网页源码经常存在换行、空格text()精确匹配容易失败改用contains()//div[contains(text(),文章名称)]/following-sibling::div[1]四、方案3父子、祖先层级定位1. parent:: 直接获取父节点//div[contains(text(),发布时间)]/parent::div2. ancestor:: 向上查找任意祖先节点适合多层嵌套向上寻找指定父容器//div[contains(text(),2026-08-14)]/ancestor::div[classcontainer]3. child:: 子节点等价直接使用 /标签//div[classcontainer]/child::div[1]五、方案4组合多邻居条件增强稳定性页面结构复杂时单一锚点容易匹配到多条结果可以叠加条件过滤。示例找到「内容摘要」后面第一个div并且父容器是container//div[classcontainer]//div[contains(text(),内容摘要)]/following-sibling::div[1]六、方案5多标签混合、嵌套场景实战测试HTML结构多层嵌套无特征div classbox p标题/p div span无用信息/span span目标内容/span /div /div需求根据p标题/p定位找到后面div内部第二个span//p[contains(text(),标题)]/following-sibling::div//span[2]七、常用XPath轴完整速查表语法作用following-sibling::tag当前节点之后的同级兄弟preceding-sibling::tag当前节点之前的同级兄弟parent::tag直接父节点ancestor::tag所有上层祖先节点child::tag直接子节点following::tag文档中出现在后面所有节点不限层级preceding::tag文档中出现在前面所有节点不限层级区分重点following-sibling只找同级following查找所有后代以外后续全部节点范围更大尽量优先使用 sibling减少误匹配。八、高频踩坑汇总坑1XPath下标从1开始很多人习惯写[0]# 错误[0]匹配不到任何元素 tree.xpath(//div[0])坑2文本存在换行、空格直接text()完全匹配失败❌ 错误写法//div[text()文章名称]✅ 推荐写法//div[contains(text(),文章名称)]坑3混淆following-sibling和followingsibling 仅限同级范围更小不容易匹配到页面其他位置元素稳定性更高。坑4页面动态渲染JS生成内容lxml只能解析静态HTML。如果元素由JS渲染lxml无法获取节点需要使用DrissionPage、Selenium加载页面后再执行XPath。坑5匹配结果为空列表直接下标取值# 危险找不到元素会直接报错 data tree.xpath(xxx)[0] # 规范写法 result tree.xpath(xxx) if result: data result[0]九、实战完整示例可直接复制运行from lxml import etree html div classinfo div用户名/div div张三/div div手机号/div div13800138000/div /div tree etree.HTML(html) # 通过锚点文本抓取后面无特征div username tree.xpath(//div[contains(text(),用户名)]/following-sibling::div[1]/text()) phone tree.xpath(//div[contains(text(),手机号)]/following-sibling::div[1]/text()) print(用户名, username[0] if username else ) print(手机号, phone[0] if phone else )十、方案选型建议优先方案锚点文本 following-sibling / preceding-sibling页面少量增减其他无关标签只要锚点文本不变定位依然有效稳定性最强。备选方案位置索引[n]仅用于页面结构永久固定、不会改版的场景。兜底方案多层祖先路径组合利用外层父容器特征缩小查找范围降低误匹配概率。总结面对没有id、class、独有属性的元素不要直接硬编码顺序路径。核心思想利用页面上有稳定特征的周边元素作为锚点借助XPath轴语法实现跨节点定位。following-sibling::、preceding-sibling::是日常爬虫解决无特征元素最核心的两个语法。掌握这套思路绝大多数缺乏标记的网页节点都可以稳定定位大幅提升爬虫鲁棒性减少页面改版带来的维护成本。