一套稳定耐用的采集规则,本质上是在准确性和韧性之间找平衡。规则既要命中所需要的字段,也要能扛住页面结构和加载方式的偶尔调整。很多采集任务中途夭折,往往不是方向错了,而是规则写得过于脆弱,一次页面改版就让整套逻辑失效。下文从规则的基本构成讲起,围绕定位方式的选择和高频故障的排查给出可落地的处理思路。
任何一套采集规则,都可以被拆解成三个相互配合的环节,清楚理解它们的边界,是写出高质量规则的前提。
动手写规则前,先判断任务属于列表型还是详情型。列表页通常只需采集条目链接和少许摘要,逻辑简单;详情页字段多,且不同页面之间字段缺省情况不一,容错要求明显更高。以房产信息为例,列表页拿标题和链接就行,但进入详情页后,各楼盘在户型、面积、朝向等字段上可能有的有、有的没有,规则就得考虑缺省值如何处理。
定位方式直接决定规则的生命周期和排查成本,这世上没有放之四海皆准的方案,只能根据页面本身的特征来做权衡。
当页面嵌套层级深、标签结构乱时,XPath的表达能力优势明显,比如用 //div[contains(@class, 'mod')]//p 就能框选某个区块内的全部段落。不过,路径一长,调试时的阅读负担就上来了,而且它对层级变化极为敏感,哪怕只是多包了一层容器,规则就可能直接失效。
如果页面class命名清晰、结构又不太深,那么一句 .item-title 就能利落地拿到值。可当同一个class在页面上被大量重复使用时,就得靠子选择器或伪类来缩小范围,比如从列表里取第二个条目的标题,可以写成 .list li:nth-child(2) span 这样。
目标数据藏在非结构化文本中时,正则往往是唯一能开锁的钥匙,比如从客服聊天记录里抽出订单号。但它灵活过头,难写难读,一个疏忽就会误匹配到不想要的内容。能用XPath或CSS解决的场景,就别把正则请出来。
如今很多页面内容靠接口异步加载,用开发者工具看网络面板,找到真实的XHR请求,直接解析JSON响应,远比对着渲染后的DOM树抽字段来得稳。JSONPath取值直接,语法和XPath相近,上手也不难。
这里有一个值得刻在脑子里的原则:尽量别用绝对路径。绝对路径从根节点一路写到底,页面只要哪天多套了一层div就全军覆没;相对路径只看目标元素周边的上下文关系,对改版的承受力强得多。
分页看着简单,翻车频率却极高。多数站点把页码放在URL参数里,循环替换就行。但有两类变数要注意:一是页码藏在JavaScript发起的请求体里,这时得同步修改POST数据;二是部分站点虽然URL不变,但返回内容取决于Cookie或时间戳参数,比如列表接口带了个由JS生成的签名。对此,合理的策略是先抓取首页响应,再从中提取翻页所需的参数,再拼出后续页面的请求。
采集跑久了,难免遇到各种怪问题。以下几条是根据实操经验整理的常见故障和处理方向。
通常是因为页面前端频繁调整DOM结构,比如改了class名、新增了嵌套层,或者把静态内容改成了异步渲染。建议优先用相对路径和包含匹配(如contains),尽量缩短路径深度,实在频繁变动,就考虑改走接口方案。
如果目标字段本身有明确的边界特征,可以先用XPath或CSS取到更小的文本块,再在这个小范围内用正则抓取,能降低匹配成本。另一个思路是把正则匹配的部分拆成多步:先按分隔符切分,再定位目标片段。
关键是看响应内容。如果页面上出现了滑块、验证码图片或类似提示文字,一般是IP或账号被限流,跟规则本身无关。此时应检查请求头(如User-Agent、Referer)是否完整,并适当降低请求频率,必要时设置随机延时。
一套扎实的采集规则,离不开清晰的任务拆解、贴合页面情况的定位方式,以及面对动态内容和异常响应时的应急机制。建议在规则上线前,先拿一小批真实页面做试跑,确认字段完整性和容错逻辑都到位再放开全量抓取。同时,给规则留好日志输出接口,方便日后定位是哪一步出了问题。优先采用相对路径,对接口型数据直接解析JSON,处理文本时克制使用正则,这三条是让采集脚本长期稳定运行的关键。