几年前,我搭了一个 Python 编程教程网站,顺便加了些在线写代码、交作业和打卡的小功能。这几年精力有限,网站也没怎么做推广,基本就靠老用户和自然搜索维持着。
最近服务器要续费了,我一查,十几年前的老机型续费价格实在不划算,不如重新买台新机器,把数据迁过去。
就在迁移服务器、顺便翻看系统日志时,一个让我头皮发麻的现象浮出水面:日志里塞满了给其他用户主页的“点赞”操作。

一、异常初现
第一反应是:不会吧,这功能还有这么多忠实用户天天在用?
可细看之下,情况完全不对劲:
- 这些点赞行为全部来自匿名用户。
- 除了“访问主页”和“点赞”,没有任何其他操作记录。
这明显不是真人干的事。
好奇心被彻底勾起来了。我把手头的线索捋了捋:
- 请求高度集中在“用户主页”和“点赞”这两个接口上。
- 全部是未登录的匿名请求。
- IP 地址极其分散,查了几个归属地,全国各地都有,甚至还有国外的 IP。
- 没有固定的时间段。
最让我震惊的是:顺着日志往前追,这类请求居然从 9 年前就开始了,一直持续到现在!而且近两年的频率明显更高。

二、排查之路
一开始,我脑补了几种可能:
- 读者练手写爬虫? 我之前还专门弄过一个“靶子网站”让大家练手。如果是哪个读者拿主站来实践,似乎也说得通。
- “脚本小子”在扫漏洞? 以前确实发生过类似的事。
但这俩猜想很快就站不住脚了——谁家读者练手或者脚本小子扫漏洞,能一口气坚持 9 年?这完全不合常理。
那会不会是恶意攻击?这个想法就更离谱了。持续攻击是有成本的,谁会闲得发慌,花 9 年成本来“攻击”一个偏公益的学习网站?
排除了这些选项,剩下的只有一个可能:这是某种自动化程序在跑。
幸好,当年设计点赞功能时,我顺带记录了请求的 IP。我开始随机挑一些 IP 查归属地,一开始由于太分散,没看出什么规律。直到我查到一个早期的 IP,它的反向解析记录让我瞬间清醒了。

Spider!搜索引擎的爬虫蜘蛛!
我一下全明白了。困扰我 9 年的“攻击者”,竟然是搜索引擎的内容采集脚本。
真相就此揭开:
- 这些网页是公开的,用户页面和点赞链接不需要登录就能访问。
- 一个用户的主页上,既有给该用户点赞的链接,又有通往其他用户主页的链接。
- 当爬虫顺着页面的链接爬进“点赞 URL”时,服务器忠实地执行了点赞逻辑,导致点赞数和排行榜发生了变化。
- 搜索引擎发现页面内容“更新”了,于是再次派出蜘蛛来抓取“新”内容。
- 一个完美的死循环形成了:蜘蛛抓取→触发点赞→内容变动→页面更新→再次抓取……
就这样,搜索引擎蜘蛛在我的网站里陷入了一个长达 9 年的无尽循环。
为了验证这个设想,我去搜索引擎里搜了一些用户主页上的随机文本。这些文本平平无奇,根本不含“编程”、“Python”这类关键词。但果不其然,我网站的页面高高挂在了搜索结果前列。
更有意思的是,连相关 AI 生成的结果里,也会莫名其妙地关联到我的网站——看来这些被蜘蛛抓去的无意义页面,还被拿去当大模型的训练语料了。

不过在我修复问题之后,图中这类关联就已经消失了。
三、修复方案
看到这里,懂 Web 开发的读者可能要吐槽了:“一个点赞操作,你居然设计成 GET 请求?还允许未登录操作?”
我回想了一下,当年写这段代码时,大概是想方便大家在微信里直接转发链接“喊朋友来集赞”,所以才做成了这种无需登录、点击即赞的极简设计。当时记录点赞 IP,也只是为了做个简单的防刷限制,没想到给搜索引擎蜘蛛留了这么大一个口子。
发现问题后,我先是尝试更新 robots.txt,想禁止蜘蛛抓取点赞相关路径。但观察了几天,收效甚微,已经深陷死循环的抓取依然在进行。
既然现在网站早没了这种社交集赞的需求,我索性来了个“根治”:
- 直接关闭匿名点赞权限,改为必须登录后才能查看和操作。
- 重构并更换了新的 URL 地址,将所有写操作规范化。
世界终于清静了。
四、经验总结
一次常规的服务器迁移,竟意外揭开了这段 9 年的“误会”。虽然没造成什么严重破坏,但回顾整件事,对做 Web 开发和编程学习的朋友来说,仍有几个典型的教训值得吸取:
-
遵守 HTTP 规范,GET 应保持“幂等”
GET 请求应该只用于获取数据,任何会产生数据变更的操作都应使用 POST、PUT 或 DELETE 请求。如果当初这样设计,爬虫根本不会触发“点赞”和后续的页面更新。
-
别低估搜索引擎蜘蛛的“执着”
爬虫的逻辑非常机械:只要 HTML 里有 <a href="..."> 标签,它就会顺着爬过去。如果你的 URL 设计不规范,或者包含了能形成闭环的逻辑链条,蜘蛛就可能陷入其中,变成一种长期的、无意的“软 DDoS”,白白消耗服务器资源。
-
robots.txt 是君子协定,不是安全防火墙
它只能起到引导作用,并非强制约束。有些爬虫会直接忽略它;而且对于已经建立索引、甚至形成死循环的历史 URL,仅靠 robots.txt 很难立刻见效。涉及权限和逻辑的安全边界,必须在后端代码层面做好防护。这其实也属于一种常见的技术债,最好定期排查。
-
警惕“技术债”,定期审查日志
很多年前为了“图方便”或“赶进度”写的临时代码,往往会成为日后的隐患。即便是一个看似不起眼的小功能,如果缺乏身份校验和频次限制,在运维的长期运行中也会产生意想不到的副作用。
你在写代码或维护产品的过程中,有没有遇到过什么奇葩的 Bug 或历史遗留问题?欢迎在 云栈社区 分享你的故事。