爬虫、洪水与机群:一年来守护数字馆藏开放的历程
摘要
Wellcome Collection 介绍了 2026 年年中 AI 相关爬虫流量激增以及机器人洪泛对其数字馆藏造成的压力,以及他们如何通过更新 robots.txt、CDN 限流和流量压缩来应对。文章详细描述了不断升级的自动化流量浪潮,其中包括类似僵尸网络的洪泛攻击,以及为保持其开放目录和 API 正常上线所做的工程工作。
<p><a href="https://lobste.rs/s/4sgimt/crawlers_floods_fleets_year_keeping_our">评论</a></p>
查看缓存全文
缓存时间: 2026/10/19 07:58
# 爬虫、洪水与舰队:让数字馆藏保持开放的一年
来源:https://stacks.wellcomecollection.org/crawlers-floods-and-fleets-a-year-of-keeping-our-digital-collections-open-10af777199c4?gi=b410f7dad041
Robert Kenny (https://medium.com/@kenoir?source=post_page---byline--10af777199c4-----------------------------------------)
按回车键或点击可查看完整图片
*一间印刷工坊:左侧是一台印刷机,右侧和中间是忙碌于各种工作的工人* (https://wellcomecollection.org/works/pegut4ja)*。根据 L.J. Goussier 创作的版画。来源:Wellcome Collection。公共领域标记。*
Wellcome Collection (https://wellcomecollection.org/) 是一座免费的博物馆和图书馆,我们的馆藏在线上更容易获取。无论你身在何处,都可以搜索我们的目录 (https://wellcomecollection.org/collections)、阅读数字化手稿或以开放许可协议 (https://creativecommons.org/share-your-work/public-domain/pdm/) 下载图像。我们还通过公共目录 API (https://developers.wellcomecollection.org/api/catalogue) 和 IIIF (https://iiif.io/) 以机器可读的形式发布同样的资料——IIIF 是一种标准,可以让其他人的图像查看器将我们的图像与他们自己的图像并列展示。任何想要大规模利用我们馆藏的人都有现成的途径可循。
过去一年中,我们越来越多的流量来自其他途径。七月的一个周一上午,我们的大部分搜索开始出现失败,原因是数千个不同地址在几分钟内向我们的搜索页面发起了单个请求。那是最显眼的一次,但并非第一次。本文描述了我们在 2026 年 6 月至 9 月间观察到的流量,以及我们的应对措施。
### 第一波浪潮:具名爬虫与 robots.txt
按回车键或点击可查看完整图片
*十只蜘蛛,展示了形状和颜色的多样性* (https://wellcomecollection.org/works/g8t55654)*。水粉画。来源:Wellcome Collection。公共领域标记。*
第一波浪潮发生在 2026 年 6 月初,这是大多数图书馆都会熟悉的情况 (https://www.glamelab.org/products/are-ai-bots-knocking-cultural-heritage-offline/)。来自大型科技公司的 (https://en.wikipedia.org/wiki/Web_crawler) 爬虫,各自标明自己的名称,无论昼夜都以相同的频率抓取我们的页面和脚本。其中一家在四天内发起了超过 250 万次请求。我们在账单中比在日志中更早注意到它:6 月初预算警报响起,我们云网络中数据出网的费用自一月以来上涨了近四倍,而请求量只增长了大约一半。
我们发现,大部分费用实际上来自我们自己的系统内部。多年来,我们一直在每次页面构建时从未压缩的 IIIF API 获取数据,并没有出过问题。但爬虫的请求量使这种做法难以为继。我们在自己这边做了一个小改动来压缩这部分流量,IIIF API 的供应商也在他们那边做了配合修改,结果将这部分流量削减了超过九成。
接下来我们着手处理爬虫本身,重写了我们的 (https://en.wikipedia.org/wiki/Robots.txt) robots.txt,要求为 AI 模型收集训练数据的爬虫远离,同时仍然欢迎那些被 AI 助手使用的爬虫。我们还在 (https://en.wikipedia.org/wiki/Content_delivery_network) 内容分发网络(CDN)上配置了 (https://en.wikipedia.org/wiki/Rate_limiting) 速率限制作为补充手段。CDN 是位于我们网站前方的一层,从这里开始我们称之为"边缘"(edge)。五天之后,我们自身系统的负载大幅下降,说明这项改动生效了。我们认为延迟的原因是最繁重的爬虫需要时间来获取新的 robots.txt 规则,并处理它此前已经建立的队列。
### 第二波浪潮:针对搜索页面的分布式洪水
按回车键或点击可查看完整图片
*门农巨像,在尼罗河泛滥期间拍摄* (https://wellcomecollection.org/works/be84b3up)*。Louis Haghe 根据 David Roberts 原作制作的彩色石版画,1849 年。来源:Wellcome Collection。公共领域标记。*
7 月 6 日早上,我们的搜索页面在七分钟内收到来自约 10,000 个不同地址的约 10,000 次请求,搜索随即停止工作。几乎所有这些地址都只发送了一次请求,每个请求都带有看起来正常的浏览器标识和不同的搜索筛选条件组合,因此请求无法从缓存中获得回答,直接涌入了我们的搜索服务。不到五分钟,不堪重负的服务几乎向所有人返回了错误。
我们现有的边缘规则是根据请求的来源来判断每个请求的:它的地址、它声称的浏览器或它所在的国家。来自全球各地、每个地址只发一次请求的流量,可以畅通无阻地通过所有这些检查。而在前一天凌晨发生的一次集中爆发,峰值达到每分钟 40,000 次请求,来自每个地址的请求数量足以触发我们的速率限制,大部分在几分钟内就被阻断,网站始终保持在线。我们认为这两天之间的对比恰好概括了机器人流量的变化。
按回车键或点击可查看完整图片
*2026 年 7 月 5 日至 6 日每小时的请求数和服务器错误数。7 月 5 日的爆发在请求数上表现为一个尖峰,大部分被速率限制拦截。7 月 6 日的洪水在请求量上几乎不可见,因为量很小,但它是唯一一个网站返回错误的时段。数据来自我们的内容分发网络的每小时统计。*
我们是从尝试使用网站的人那里得知这次故障的,而不是从我们的监控中获知的。虽然我们已经为目录 API 设置了健康检查,但它从未连接到任何能触发人员告警的系统。我们在当天上午、下一次变更上线之前就修复了这个问题。
选定的修复方案是在搜索页面前方增加一道 JavaScript 挑战。该挑战要求访问者的浏览器在请求继续之前先运行一小段 JavaScript。人的浏览器会毫不知情地执行一次,但无法运行 JavaScript 的脚本就无法继续前进。因此,我们 robots.txt 欢迎的 AI 代理和构建链接预览的服务也一并被拦在了外面。失去它们访问搜索页面是我们为确保搜索对人可用而接受的代价。由于之前的挑战尝试曾经导致网站崩溃,我们首先在预发布环境(staging environment)中测试了这次的方案。在那里,一个 (https://en.wikipedia.org/wiki/Headless_browser) 无头浏览器验证了搜索仍然正常工作。上线后,同样的检查在每个工作日每半小时运行一次,持续了两天。
我们还屏蔽了非常过时的浏览器版本,几小时内流量就切换到了更新的版本标识。第二天凌晨三点,其中一些流量已经在使用真正的无头浏览器来解决挑战,每小时有数百次请求重新到达了我们的服务器,只不过现在每次请求的代价从一次廉价的单个请求变成了一整个完整的浏览器会话。我们的应对是采用一个成本更低的规则:人的浏览器会在每次请求中告知我们它偏好的语言,而大量的脚本化流量没有这样做,因此我们拒绝了缺少这个字段的搜索请求。它在拦截机器人之前先拦截了我们自己的测试浏览器,这说明规则会奏效。上线不到半小时,尝试挑战的数量就显著下降了。
到那个周末,挑战及其配套规则已经拦截了我们搜索页面的大部分自动化请求,而通过的流量主要是人。我们将搜索页面设置为不可缓存,选择在边缘层而非后端拦截流量。两周后,机器人仍然以同样的频率到来,但边缘层现在将大部分拦在了外面而不是应答它们,到达我们服务器的流量主要是人。
按回车键或点击可查看完整图片
*2026 年 6 月 1 日至 9 月 24 日 wellcomecollection.org 按边缘动作分类的每日请求数。6 月被拦截请求的尖峰是速率限制在吸收一次四天的爆发;9 月中旬起被挑战和被拦截请求的上升是本文撰写时正在发生的激增。数据来自我们的 (https://en.wikipedia.org/wiki/Web_application_firewall) Web 应用防火墙的每日统计。*
### 第三波浪潮:条目页面上的浏览器舰队
按回车键或点击可查看完整图片
*格林威治皇家海军医院,前景中有船只和划艇* (https://wellcomecollection.org/works/duq2vt7j)*。Millam 于 1823 年根据 T. Bowles 1753 年原作制作的版画。来源:Wellcome Collection。公共领域标记。*
八月中旬,模式再次改变。这次是在我们提供数字化条目查看器的页面上,我们每天收到来自 20 万到 33 万个不同地址的请求。它们来自南亚、东南亚和拉丁美洲的 (https://en.wikipedia.org/wiki/Residential_proxy) 住宅连接,每个地址每天只发出几次请求,远低于我们为个人设置的任何限制阈值。它们运行的是真正的浏览器,包括我们的查看器代码本身,按照我们现有的规则,看起来就像是正在使用我们查看器的读者。在这些页面背后的 IIIF API 上,请求量大约翻了一番,从每天约 900 万次增长到 1700 万至 2000 万次,在最繁忙的日子里,超过 60 万个不同地址从我们这里获取图像。
在梳理那些日志时,我们注意到最大的单一请求来源竟然是我们自己的网站。每当它构建一个条目页面时,它都会向 IIIF 平台请求一个描述该条目可能所属的更大集合的 (https://iiif.io/api/presentation/3.0/) manifest(清单),这对一小部分作品而言是有意义的。然而这个请求十次有九次会失败,而对于不属于任何更大集合的作品,即使请求成功了,结果也会被丢弃。它每天产生了多达 140 万次失败请求,构成了我们 IIIF API 上的错误基线。对网站代码的一个小改动就消除了这个请求。
## 订阅 Robert Kenny 的文章
免费加入 Medium 即可获取这位作者的最新更新。
记住我以便快速登录
八月下旬我们选择将 JavaScript 挑战扩展到这些页面后,舰队的大部分并没有尝试解决挑战,因此被拦在外面。大约一周内,它们开始尝试并解决了几乎每一个挑战,到九月初,到达我们服务器的流量回到了之前较高的水平。
在那之后,我们试用了我们 CDN 供应商提供的一个 (https://docs.aws.amazon.com/waf/latest/developerguide/waf-bot-control.html) 机器学习机器人检测器,以观察模式运行了三天。它没有发现任何能将该舰队与我们的读者区分开的东西,因此我们没有采用它。
我们自己的边缘日志被证明更有价值。自从开启日志记录以来,它一直在记录每个访问者软件建立加密连接的方式的 (https://en.wikipedia.org/wiki/TLS_fingerprinting) 指纹,其作用类似于软件的签名。舰队五分之四的流量共享同一个指纹,无论它声称是什么浏览器,而且它整夜以恒定的速率运行。由于我们的英国读者遵循白天的时间曲线,我们认为大部分舰队是同一个程序伪装成多个浏览器。我们还没有基于这一发现构建规则,该舰队目前仍然能够通过。
按回车键或点击可查看完整图片
*一位医生通过单片眼镜查看一排病人* (https://wellcomecollection.org/works/qtdcvht3)*。钢笔画。来源:Wellcome Collection。公共领域标记。*
### 批量采集器与 IIIF API
按回车键或点击可查看完整图片
*农业:一台由马匹牵引的收割机* (https://wellcomecollection.org/works/bxj683ds)*。J. Pass 于 1816 年制作的彩色版画。来源:Wellcome Collection。公共领域标记。*
除了条目页面上的浏览器舰队之外,脚本化的采集器还在从我们的 IIIF API 大批量拉取 PDF 和全尺寸图像,而 API 按其设计目的为它们提供了服务。一个采集器将自己分散在从云服务商租来的数千个地址上,在两周内下载了 6 TB 的 PDF。另一个则从电信运营商租来的一段 IP 地址范围中的 11,0000 个地址按数字顺序请求我们的图像。
IIIF API 本来就是为脚本读取而设计的,而且它必须在我们的图像被嵌入别人的页面或在我们不控制的查看器中打开时正常工作,在那些场景中没有人能回答一个挑战,因此我们在搜索页面上使用的手段会把它搞坏。相反,我们设定了预算:无论某个采集器或网络使用了多少个地址,每分钟只允许固定数量的请求。IIIF API 的供应商还增加了针对每个地址的全尺寸图像(服务成本最高的请求)限制,并帮助我们将其设定在一个足够高的水平,使得一家读者从单一地址访问我们的大学图书馆不会被误伤。
日志中的许多脚本会用项目名称或联系方式来标识自己。对于那些请求速率在我们可以服务范围内的,我们没有干预;对于超出范围的,我们给了它们一个预算。我们的原则是:一个大规模用户如果告诉我们它是谁,就能得到善意推定,而我们不会将这种推定给予一支伪装成一万人的舰队。
### 使用 AI 助手进行分析
本文中描述的大部分分析和实施工作都是由 AI 编码助手完成的,它们对接我们的代码仓库和云端日志工作,这意味着在这一年中的大部分时间里,我们是在让一个机器人去对抗另一个机器人。在七月那次故障的当天上午,从提出审查日志的请求到形成清晰的流量画像,大约只用了九分钟。在八月和九月间,它找到了被丢弃的 manifest 获取请求、被拒绝的 (https://en.wikipedia.org/wiki/Robots.txt) robots.txt 以及共享指纹,有些是回答我们的问题时发现的,有些则来自我们未曾想到的调查方向。
它们也犯过足够多的错误,以至于我们需要核实它们告诉我们的内容。其中一个将我们自己的在线状态检查误判为洪水的一部分,将六月流量的结束解释为爬虫离开了,并且三次修改了成本估算。尽管有这些错误,AI 助手仍然保持了实用价值,因为每一项变更都先进入预发布环境,每一条规则都在真实浏览器中进行了测试。关于拦截什么、放行什么以及在公开场合说什么的决定,都是由我们根据它们收集到的证据做出的。
### 我们学到了什么
我们的故障和最大的账单都源于我们自己这边将廉价请求变成昂贵请求的事情:未压缩的响应、不可缓存的页面以及结果被丢弃的获取请求。当下次再发生时,我们会首先查看一个请求到达我们自己服务器后所产生的实际成本。
在这一年之前,基于请求自身声明的信息——例如地址、浏览器或国家——制定的规则基本上是足够的。当流量分散到足够多的地址后,这些规则就失效了。基于请求行为——例如能否运行 JavaScript——制定的规则,只在发送方学会应对测试之前有效,而每次发送方学会应对所花的时间不到一周。到目前为止真正有效的是针对每个采集器或网络每分钟能请求多少的预算限制,而我们还没有为那支浏览器舰队制定这样的预算。
我们认为,让 AI 助手在几分钟而非几小时内回答关于我们的日志和代码的问题,改变了我们能够提出的问题的数量,而这一年的几个最有价值的发现都来自那些我们原本没有时间去提的问题。这也意味着我们当中一位此前从未调查过这类流量的同事,能够在不从零开始学习或在每一步都依赖同事的情况下承担起大部分工作。
流量已经
相似文章
Meta和阿里巴巴的AI爬虫几乎摧毁了一个由志愿者运营的LGBT历史档案库
来自Meta和阿里巴巴的失控AI爬虫几乎使一个志愿者运营的LGBT历史档案库崩溃,凸显了科技巨头激进网络抓取的风险。
花了一个下午让我的网站更AI友好。第二天AI流量增长了12倍
一位开发者通过修复robots.txt、添加llms.txt、改进语义HTML等方式优化网站以适应AI爬虫,次日AI流量增长了12倍。
每个 AI 智能体抓取网站的方式截然不同。以下是 3 个月、1100 万事件日志显示的真实情况。
对 34 个网站上 1100 万爬虫日志的分析揭示了不同行为:GPTBot 无视 robots.txt 持续抓取;Google 的爬虫频繁检查规则;ClaudeBot 的抓取速度正在快速提升;Bytespider 是最重的爬虫。这些发现表明,SEO 正从以 Google 为中心转向针对 AI 智能体的页面选择进行优化。
爬虫情况更新
关于AI爬虫机器人日益严重的问题的最新更新,这些机器人导致网站不堪重负,并探讨了住宅代理网络及其对开放网络的影响。
@heynavtoor: 一个获得六万星级的网络爬虫在几天内建成。由一个开发者完成。因为一个“16美元的开源”工具让他愤怒。六万多……
Unclecode 创建了 Crawl4AI,一款免费开源网络爬虫,能将网页转换为干净的 Markdown 格式供 AI 模型使用,起因是对付费替代方案感到不满;该项目已获得 60,000 个 GitHub Star,月下载量超过一百万。