上周三凌晨两点,我的Slack又响了。客户问为什么导出的CSV文件里,价格列全是空的。我打开日志,没有报错,没有异常,程序"正常运行"了72小时——只是什么都没抓到。

问题出在一行写了三年的代码re.findall(r'

', html)。前端团队把class="price"改成了class="listing-price",没有通知任何人。我的"爬虫"其实是个布局传感器,只对特定的HTML结构有反应。结构一变,它就成了哑巴。

打开网易新闻 查看精彩图片

这个季度我重写了Idealista的爬虫,第一件事就是删掉所有正则表达式。不是因为我讨厌正则,而是因为用正则解析HTML本质上是在赌:赌前端工程师不会重构,赌产品经理不会A/B测试,赌那个div永远不会被包进另一个span里。这三件事没有一件值得赌。

在写下一行re.findall之前,先过一遍这个三问清单:

第一,有没有稳定的无障碍属性?getByRole('heading', { name: /price/i })比任何class选择器都活得久。class名是给人看的,无障碍标签是给机器读的,改前者的成本远低于后者。

第二,数据真的在渲染后的HTML里吗?很多时候你要的东西其实藏在