对真实爬虫进程做 SIGKILL 随机杀死再续爬的实验:只放内存重复抓取平均 112 个;JSON 直接覆盖写 20 次里有 1 次状态文件损坏,原子改名 0 次;SQLite 每个 URL 提交一次重复最多 8 个(在途请求数)、几乎不增加耗时(0.55 对 0.54 秒),而整体重写 JSON 让耗时翻倍(1.12 秒)。
实测多文档事务:事务内读到开始时的快照,事务外的提交看不到;事务之间的写冲突 4 ms 内报 WriteConflict(code 112,带 TransientTransactionError),事务外的写入则等待事务结束(等了 1,526 ms);16 线程 with_transaction 计数 1600 次一个不丢(重试 1,492 次);快照隔离下的写偏斜让在岗人数变成 0。
实测 asyncio 爬虫收到信号的行为:默认 SIGINT 取消 8 个在途请求(完成 0 个,19 ms 退出);用 add_signal_handler 优雅停止则让 8 个在途请求完成(313 ms),队列剩下的 192 个可保存;SIGTERM 在没有处理器时直接杀死进程;退出用时等于在途请求剩余时间。
实测 URL 规范化对去重的影响:20 组等价写法里 yarl 合并 8 组、w3lib 10 组、自写语法规范化 11 组、再加语义规范化 15 组;1000 个页面 8 种写法共 8000 个 URL,不规范化是 8000 个“不同的”,只做语法规范化 5000 个,加上排序参数、去追踪参数、合并双斜杠后恰好 1000 个。
用 Node 的 WHATWG URL 对照 Python urljoin:36 个相对链接用例有 11 个结果不同(反斜杠、前后空格、中文编码、大写主机、:80、https:foo 等);urljoin 不过滤 javascript:、file:// 等 scheme;lxml 的 make_links_absolute(resolve_base_href=False) 实测仍应用 <base>;重定向后必须用最终 URL 当 base。
实测 100 万个 URL 的去重结构:set 存完整 URL 128.0 MiB,存 64 位哈希 66.3 MiB,Bloom 过滤器 1% 误判率只要 1.1 MiB;Bloom 实测误判 1.036%(理论 1.004%),加到 3 倍容量时误判升到 43.6%;32 位哈希在 100 万个里就有 127 个撞车。
构造一个响应取决于方法、请求体、Accept-Language 和 Cookie 的本机服务器:180 个请求有 131 种不同的内容;只哈希 URL 去重只拿到 62 种、漏掉 69 种(40 个 Accept-Language 版本、10 个 Cookie 版本、19 个 POST 请求体);把方法、请求体、关键请求头都放进指纹才拿到全部 131 种。
用合成语料量 SimHash 近似去重:只对正文做时,原文与改 5% 的变体汉明距离中位 4、不相关的两篇中位 18,k=3 召回 47.6%、误报 0;把共用的站点模板一起做,不相关的两篇距离中位降到 6,k=3 误报 37005 对;改用词的 3 元组特征后距离分布整体拉开。
实测事务的生命周期上限:默认 60 秒;事务外的写入会等到过期事务被中止(上限调到 5 秒时等了 5,357 ms);过期后继续操作与 commit 都报 251 NoSuchTransaction 且修改回滚;生命周期不因有操作续期;中止不是准点——默认 60 秒的事务 70 秒时仍能提交成功,89 秒才被清理。
实测事务在 oplog 里的样子:提交的事务只写 1 条 applyOps 条目(op=c,ns=admin.$cmd),3 个操作装在里面,用 lsid + txnNumber + prevOpTime 链起来;不放进事务则每个操作一条;update 存 diff;提交标记在 config.transactions 的 state: committed;中止的事务不留痕迹;大事务拆成 partialTxn 加一条带 count 的最后条目。
在一个带四类陷阱(无限日历、URL 里的随机 sid、288 种筛选参数组合、相对链接循环)的本机站点上真实抓取:无防御抓 2000 个页面浪费 1738 个;去掉 sid 把预算转给日历陷阱;每个 URL 模板最多 50 个只找到 103 / 263 真实页;放宽到 300 并配合去 sid 和路径重复检测才找到全部且结束。
在抓取过程中让数据不断新增和删除:偏移量分页(最新在前)返回 1148 条中重复 148 条,随机删除时漏掉 59 条;最旧在前仍然漏掉 46 条;游标分页和快照分页在新增、删除、新增加删除三种变化下都没有重复也没有漏掉。