4月6日夜里十点二十三分,星辰科技的抓取程序取得第一条联网数据。
拨号成功前,它已经忙音六次。楼上五金店老板每隔十分钟便踩一下地板,提醒马飞电话费正从押金里扣。半地下室的折叠床没地方展开,马飞只好坐在装手册的纸箱上,膝盖顶着桌沿。
页面来自一所高校的公开服务器,正文只有两百多字,介绍实验室研究方向。程序把标题、地址、更新时间和文本内容写入本地文件,耗时四十七秒。
马飞在日志第一行手写:
文档000001,来源公开,抓取成功。
接下来两个小时,程序又下载了六十三个页面。
第六十四个页面让它陷入循环。
站点日历给每一天生成一个新地址,程序不断沿“下一天”前进。即使页面内容几乎相同,地址也永远不会重复。电话计费表上的分钟数不停增加。
马飞发现时,已经浪费了二十七分钟。
他立刻断线。
电话清单上多出四元六角。那是他一天多的饭钱。楼上老板拿算盘算完,问日历上的字到底值不值这个价。
“不值。”马飞把钱从生活费信封里拿出来,“所以今晚不能再让它碰同一个坑。”
老板收了三元,剩下一元六角记在下个月库存维护里。他嘴上说不是赊账,只是怕马飞饿倒以后没人修程序。
未来成熟爬虫会有内容指纹、路径规则和站点级抓取预算。此刻,他只写了最基本的地址去重。知道缺什么不难,难的是在一台旧486上用尽可能少的内存补上。
他先为正文计算简短指纹,再规定每个站点单次最多抓取五十页。若连续五页的文本相似度过高,自动暂停该路径。所有暂停必须写入日志,下一次由人工判断是否恢复。
第二天,苏雨桐看完代码,指出另一个问题。
她来时带了两个食堂馒头,进门先摸水管,再看防水铁盒。确认备份没湿,她才把一个馒头放到马飞桌上。马飞正准备说昨天新增六十三页,她已经在日志里看见那二十七分钟循环。
“你只考虑自己会不会浪费电话费,没考虑对方服务器。”
“每次请求间隔十秒。”
“多个路径并行时不是十秒。对同一站点,你有三次请求只隔了两秒。”
早期网络带宽稀缺,一台不受控制的抓取程序足以让小型服务器明显变慢。规则尚未形成,不意味着伤害不会发生。
两人给程序加上站点级队列:同一服务器至少间隔二十秒,夜间访问也限制总量。请求标识中写明“xingchencrawler/0.1”,附上联系邮箱和退出方式。
为验证限制真的生效,苏雨桐把三条不同路径同时放进队列,拿秒表守了二十分钟。程序有一次在第十九秒提前发出请求,她让马飞整段重写,不能靠多加一秒掩盖计时误差。凌晨十二点四十七分,连续三十次间隔都超过二十秒,她才在测试单上签字。
“有人会给一个爬虫写信?”马飞问。
“有人不想被抓时,总要找得到你。”
三天后,真的有人写来。
邮件来自某高校网络中心,只有一句话:
请停止访问 `/student/` 目录,其中含临时个人主页。
马飞立即把该路径加入禁止列表,删除已经取得的十一页内容,并回复说明处理结果。
第二封邮件在次日到达。
对方问:你们做的是什么?
马飞没有把“全国中文网页搜索”写得像已经存在。他如实说明,这是一项小规模公开信息检索实验,目前不对外提供服务,不保存限制目录内容,愿意接受站点管理员的抓取时间与范围要求。
网络中心回复:
实验室和公开论文目录可以保留。凌晨一点到五点访问。
这封简短的许可,成了星辰科技第一份数据边界记录。
对方还附了一份公开目录清单,列出十二个允许访问的路径。按清单抓取以后,程序不再浪费时间猜测哪些页面能进,五小时里有效页面比例反而提高了一倍。马飞把节省下来的电话费算给苏雨桐看,她只在旁边写了一句:尊重退出也能省钱,但别把省钱当成尊重的理由。
到4月底,本地语料增长到六百二十四页。数量很小,问题却成倍增加。
同一篇文章在三个地址重复。
网页更新时间不可靠。
服务器返回的中文编码与声明不一致。
有些页面只有一张图片,程序什么也读不到。
更棘手的是链接重要性。一个页面被许多站点引用,通常更值得排在前面;但在当时的中文网络里,友情链接、镜像目录和人工导航页大量存在,简单计算链接数量会把目录当成最重要的内容。
马飞写出一版迭代评分,又在第二天删掉。
不是算法错,而是样本太少。六百多个页面上的漂亮曲线没有统计意义。
删除前,他把代码复制进“暂停方案”目录,写明停用原因。未来记忆让那套思路看上去极有诱惑,苏雨桐却随手抽了二十个页面,让他盲排。所谓重要性得分最高的五页里,有三页是友情链接目录,一页是镜像站说明。
马飞把测试结果钉在墙上。楼上老板下来借订书机,看完前三行,问他是不是花了两晚证明校园黄页最有学问。
“差不多。”马飞说。
老板笑得整根水管都像在震。
“先别给自己制造高级问题。”苏雨桐说,“用户连中文词都搜不稳,链接排序排得再聪明也没用。”
她把任务拆成三项:编码识别、重复检测、基础相关性。
马飞看着被划掉的链接评分模块,承认她是对的。
他拥有未来最知名算法的方向,却必须忍住提前使用它的冲动。一个系统的成熟,不在于塞进多少未来概念,而在于当下最痛的问题是否被解决。
5月2日凌晨,抓取程序完成第一次无人值守运行。
五小时里连接中断四次,自动恢复三次;一处站点因连续错误被暂停;新增有效页面八十七个,重复页面二十三个,总电话费用控制在预算内。
天快亮时,马飞输入“液体火箭燃烧振荡”。
系统返回六条结果。
第一条正是某高校实验室公开的论文目录,标明了作者和馆藏信息。正文不在网上,但一个读者至少知道该去哪里找。
马飞把查询结果打印出来,贴在日志旁边。
打印纸还热着,字迹却有一行发浅。色带快用完了,马飞拿出来拧紧,勉强又印了一份。他把较清楚的那张寄给最初允许访问的网络中心,背面写明查询来自哪些公开目录;发浅的那张留在墙上。
早上五点零七分,五金店老板下来开门,发现马飞趴在折叠床边睡着了,手边压着电话费清单。老板没有叫醒他,只把墙角那只接漏水的脸盆往管子下挪了挪。
电脑屏幕上还停着六条结果,第一条后面是论文馆藏号。