XPath选择器:写爬虫必学,精准找网页元素不踩坑

谷德IP代理 2026-04-10 10:30:28

写爬虫的朋友,估计都遇到过这种糟心事儿:本来想抓个商品价格,结果爬回来一堆乱七八糟的广告;更坑的是,好不容易写好的代码,没跑两天,网站一改版,所有选择器全失效,白忙活一场。


其实不用愁,这种时候,XPath就能救场——它就是专门用来精准定位网页元素的“神器”。

XPath选择器:写爬虫必学,精准找网页元素不踩坑

先给大家讲个我自己的真实经历


上个月,我想爬一个电商网站的商品信息,一开始用CSS选择器写了几行代码,试了试,能正常运行,数据也顺利抓下来了,当时还挺开心。


结果呢?才过了三天,网站前端改了个版,我再运行代码,直接报错,啥数据都抓不到了。后来一查才知道,原来网页里表示价格的类名,从“.price”改成了“.sale-price”——就因为一个名字的变化,我之前写的代码全废了。


你们是不是也遇到过这种情况?真的特别让人崩溃。


后来我就换成了XPath,不再盯着类名、ID这些容易变的东西,而是根据价格在页面里的位置特征来定位,比如“商品详情页右边那个红色的数字”。


别说,还真管用!哪怕页面再改样式,只要整体结构没大变动,XPath依然能精准找到我要的元素。


这就是XPath最牛的地方:它不依赖你给元素起的类名或者ID,只看这个元素在网页文档里的“地址”和“亲戚关系”,不容易失效。


XPath到底是什么?一句话给你说透


咱们把HTML网页想象成一棵大树就好理解了:最外层的<html>是树根,里面的<head>和<body>是树干,而那些<div>、<p>、<a>标签,就是树上的树枝和树叶。


XPath呢,就是一套“找树叶”的语言——告诉你怎么从树根出发,一步步找到你想要的那片“叶子”(也就是网页元素)。


举个例子,有这么一段XPath:`/html/body/div[2]/p[1]/text()`


翻译成人话就是:从网页最根上开始,先找到body,再找到里面的第二个div,然后取这个div里的第一个p标签,最后把p标签里的文字拿出来,就这么简单。


常用写法,记住这几种就够⽤,不用死记硬背


1. 绝对路径(不推荐)


比如:`/html/body/div[1]/div[2]/a`


这种写法太死板了,就像一张手写的寻宝地图,一步都不能错。网页稍微改个层级,比如多套一个div、少一个div,这个路径就失效了,新手千万别一开始就用这个。


2. 相对路径(强烈推荐,灵活又好用)


比如:`//div[@class='price']/text()`


开头的`//`特别关键,意思是“从网页任何位置开始找”,不用从头一步步数层级,灵活多了,大部分时候用这个就够了。


3. 按属性筛选(最常用的场景)


比如找用户名输入框:`//input[@id='username']`


找指定链接:`//a[@href='https://example.com']`


还能多条件筛选,比如找类名为product、且数据类型是book的div:`//div[@class='product' and @data-type='book']`


4. 按文本内容找(CSS做不到的功能)


比如:`//button[contains(text(), '登录')]`


意思就是:只要按钮上的文字里包含“登录”两个字,不管它的类名、ID是什么,都能找到。这个在对付多语言网站的时候,特别好用。


5. 按位置索引(找第几个元素超方便)


`//ul/li[1]` —— 找ul标签里的第一个li


`//ul/li[last()]` —— 找ul标签里的最后一个li


`//ul/li[position()<3]` —— 找ul标签里的前两个li


实战演示:从知乎首页抓问题标题


咱们打开知乎首页,按F12打开开发者工具,看一下问题标题的元素结构,大概是这样的:


<h2 class="QuestionTitle">
  <a>你写过哪些实用的Python代码?</a>
</h2>


如果用CSS选择器,写法是:`.QuestionTitle a`


用XPath的话,就是:`//h2[@class='QuestionTitle']/a/text()`


但你们想过没有,如果知乎改版,把class名改成“ZhihuQuestionTitle”,CSS选择器就废了,但XPath可以这么写:`//h2[contains(@class, 'Title')]/a/text()`


翻译过来就是:只要是h2标签,它的class里包含“Title”这三个字母,不管你怎么改类名,我都能找到它——这就是XPath的灵活性!


一个小技巧,让你的爬虫更稳,少踩坑


重点来了:别用完整的绝对路径,多用电`//`和`contains()`,这俩组合起来,能避开很多改版的坑。


举个例子,你想抓某网站的文章正文,一开始可能找到的路径是:`//div[@id='article']/div[@class='content']/p`


但如果有一天,网站在article和content之间,多套了一层div,你的XPath就失效了。


改成这样就稳了:`//div[@id='article']//p`


中间的`//`表示“中间可以跳过任意层级”,不管它在article里面套多少层div,所有的p标签(也就是正文内容)都能抓到,再也不怕网站小改版了。


XPath和CSS选择器,到底该用哪个?别纠结


很多新手都会纠结,到底选哪个,其实很简单,看场景来选就好,给大家整理好了:


使用场景推荐选择
根据id或class快速定位元素CSS选择器(更快、写法更简洁)
根据文本内容找元素(比如找“登录”按钮)XPath(CSS根本做不到)
需要向上找父元素XPath(CSS做不到)
网页结构不稳定,但元素特征稳定(经常改版)XPath
做大规模爬虫,对性能要求高CSS选择器(一般比XPath快10-20%)

两个新手必踩的坑,提前避开,少走弯路


坑一:索引从1开始,不是0!


这是最容易出错的地方!咱们写Python、Java的时候,索引都是从0开始,但XPath不一样,`//div[1]`指的是第一个div,不是第二个。很多新手一开始都会写错,记牢这一点,能省很多麻烦。


坑二:小心命名空间的坑


有些网页会用XML命名空间,标签会变成<x:div>这种样子,这时候如果直接写`//div`,是匹配不到的。正确的写法是`//*[local-name()='div']`,这样就能忽略命名空间,正常匹配到div标签了。


总结


其实XPath的学习成本真不高,不用死记硬背所有语法,记住上面说的几种常用写法和避坑技巧,就能应对大部分爬虫场景。


而且一旦你掌握了它,就会发现,很多CSS选择器搞不定的难题,它两三行代码就能解决。尤其是爬那些经常改版、页面结构杂乱的网站时,XPath绝对是你的救命稻草。


你可以把它想象成一个“能听懂人话”的定位系统——你跟它说“找那个价格旁边的红色按钮”,它就能精准给你找出来,不用你一点点去抠标签、抠类名。


下次写爬虫,不妨试试用XPath来写定位,你会发现,原来网页元素不是杂乱无章的,而是一棵能按图索骥的树,抓数据也会变得简单又高效。