一家印度知识产权律所,因为内部工具需要程序化检索商标数据,把印度商标注册局的数据整个爬了下来——330万+条记录,时间跨度回溯到《商标公报》第1703期。有人问这些数据能不能做成API,他们干脆直接上线了一个免费公共接口。

这不是一篇产品宣传稿。作者说得很直白:重点是想讲讲,当你试图规模化读取政府数据源时,那个数据源到底会怎么"折磨"你,以及他们最终交付的API长什么样。

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

三个让人崩溃的细节

第一个坑:文件名格式不统一。《商标公报》目前已经出到2200多期,但不同时期的公报文件命名规则完全不同——没有文档说明边界,也没有变更日志。猜错了,返回的不是404,而是一个带着500状态码的HTML错误页。如果解析前没检查content-type,这段HTML就会悄悄变成解析器的垃圾输入。

第二个坑:一个看起来像死锁的静默截断bug。某天,他们的公报回填任务突然停止推进。团队花了不少时间排查爬虫并发逻辑,怀疑是死锁。真正的原因却很简单:HTTP客户端把响应体上限设成了2MB,而某些期次的列表页需要约2.3MB。没有报错,没有崩溃——只是行数永远比实际少,直到有人手动对比门户数据才发现差异。

第三个坑:所谓的"验证码"其实是个JSON接口。商标状态实时查询入口看起来有验证码挑战,但读一下前端实际调用的接口就会发现,那只是一个普通的JSON请求-响应——不需要无头浏览器,不需要图像识别。作者提醒:在默认掏出Selenium之前,值得先看一眼。

政府门户的通用教训

作者的总结很精辟:政府门户网站不会大声失败。它会先给你90%的数据,然后让你自己花时间发现那缺失的10%。

这个API本身刻意保持极简,只有两个只读的GET端点:

  • 按名称/类别搜索search?name=chai&class=30
  • 拉取某一期公报journal?journalNo=2145

两个端点都返回JSON数组,没有外层包装对象。分页元数据放在响应头里,而不是请求体:X-Total-CountLink头字段。

作者还附了一个只用Python标准库的最小客户端示例,几行代码就能跑通搜索请求。对于做品牌检索、商标清障工具的开发团队来说,这个免费接口可能省掉不少自己爬数据的功夫——前提是,别踩上他们踩过的那些坑。