不少站长以为爬虫是随机扫到自己的网站,其实绝大多数恶意爬虫都有明确入口:搜索引擎收录结果、外链友链、sitemap 与 RSS、开放目录,一路顺着链接爬进来。本文用 9 个问答讲清爬虫发现网站的几类入口、逐条收敛的配置方法,以及怎样从日志回溯爬虫是从哪个入口进来的。
Q:爬虫到底是怎么找到我网站的?
- 先把入口想清楚,后面的收敛才有方向。常见入口有六类:
- 搜索引擎收录与快照:收录页本身就是一份公开的 URL 清单,很多爬虫直接拿它当起点。
- 外链与友链:爬虫按链接关系扩散,友链、导航站、论坛签名、评论区里的链接都是通路。
- sitemap 与 RSS:本来给搜索引擎用的清单,恶意爬虫照样直接下载。
- 目录索引与开放目录:开了目录浏览,等于把文件结构摊开给人看。
- 接口文档与测试环境:调试页面、预发布域名往往没有鉴权,接口清单就这样交了出去。
- 历史 DNS 记录与证书透明度日志:域名和子域名会被这些公开记录暴露,爬虫按子域名逐个试。
- 核心认知一句话:拦截是被动的,收敛入口是主动的;把门减少,比在每扇门后面加锁省资源。
Q:搜索引擎收录和快照这一路要怎么收敛?
- 收录页是公开索引,你没法让搜索引擎不收录却指望爬虫找不到,正确做法是只让该公开的页面被收录。
- 三件事按顺序做:robots.txt 做声明、页面级加 noindex、sitemap 只提交要收录的页面。
- 要注意:robots.txt 只是声明,不是拦截。正规搜索引擎会遵守,恶意爬虫完全视而不见,它只能减少被动曝光,替代不了访问控制。
- 会员中心、购物车、后台这类页面用响应头明确禁止索引:
# 对不公开的路径统一加 noindex 响应头
location ~ ^/(member|cart|admin|user)/ {
add_header X-Robots-Tag "noindex, nofollow" always;
}
# 全站默认允许收录,单独覆盖上面几段即可
add_header X-Robots-Tag "index, follow" always;
Q:外链、友链会引来爬虫吗?要怎么清理?
- 会,而且这是最容易失控的一路:链路一旦被爬虫建立,它会持续回访。
- 先排查三类问题链路:质量可疑的友链(低质站点、内容站群)、被挂的暗链(页面角落里的隐藏链接)、评论区与用户资料页的外链。
- 处理方式按风险分级:可疑友链直接下线;评论区外链一律加
rel="nofollow"并开启审核;用户资料页限制外链数量。 - 顺手做一次自查,看看页面上有没有自己都不知道的导出链接:
# 抓首页,列出所有导出链接,人工确认是否有异常域名
curl -s https://www.example.com/ | grep -oE 'href="https?://[^"]+' | sort -u | head -50
# 检查是否存在隐藏链接(颜色与背景相同、零尺寸、绝对定位到屏幕外)
curl -s https://www.example.com/ | grep -oiE 'style="[^"]*(display:none|visibility:hidden|font-size:0|position:absolute)[^"]*"'
Q:sitemap 和 RSS 是不是等于给爬虫递了清单?
- 基本可以这么理解,其中 RSS 比 sitemap 更危险:它是「全站新内容清单」,很多站点还输出全文,爬虫一次订阅就能拿到全部内容。
- 三条收敛动作:sitemap 只保留需要收录的栏目页与文章页、RSS 改成摘要输出并去掉全文、给订阅地址加频率限制。
- RSS 限速很轻量,一条规则就能挡掉批量轮询:
limit_req_zone $binary_remote_addr zone=feed:10m rate=1r/s;
location ~ ^/(feed|rss|atom) {
limit_req zone=feed burst=5 nodelay;
limit_req_status 429;
add_header X-Robots-Tag "noindex, nofollow" always;
}
- 如果 RSS 对业务没有价值,最干脆的做法是直接关闭订阅入口,而不是留着再想办法限流。
Q:目录浏览和测试环境暴露怎么关?
- 这两类是最容易被忽视、后果又最重的入口,因为它们一次性暴露的是整批文件或整批接口。
- 目录浏览要显式关闭,并且对上传目录单独确认一次:
http {
autoindex off; # 全局默认关闭目录浏览
}
server {
location /uploads/ {
autoindex off; # 上传目录单独兜底,防止被继承覆盖
autoindex_exact_size off; # 连文件大小都不泄露
}
# 备份包、日志、数据库导出这类文件一律拒绝
location ~* \.(bak|sql|log|old|swp|tar|gz|zip)$ {
return 403;
}
}
- 测试环境与预发布域名必须加鉴权,就算它挂在公网上也不能裸奔:
server {
server_name staging.example.com;
auth_basic "staging";
auth_basic_user_file /etc/nginx/.htpasswd;
# 生成口令:htpasswd -c /etc/nginx/.htpasswd devuser
}
- 经验做法是把测试域名+接口调试页面列成一张清单,上线前逐条确认:能内网访问的不上公网,必须上公网的加鉴权或加 IP 白名单。
Q:怎么知道爬虫是从哪个入口进来的?
- 入口收敛不能凭猜,得用日志说话。三个视角就够定位:
- 看 Referer:爬虫的首次请求经常带着来源页面,能直接指认入口。
- 看 404 洪峰:扫目录、撞路径的爬虫会在日志里留下大量 404,且路径有规律。
- 看同一个 IP 的首次访问路径:第一次进来请求的是哪个 URL,那就是它找到你的方式。
# 1) 按 Referer 聚合,找出把爬虫引来的源头页面
awk -F'"' '{print $4}' access.log | sort | uniq -c | sort -rn | head -20
# 2) 404 请求 TOP 路径,识别目录扫描与撞库式探测
awk '$9 == 404 {print $7}' access.log | sort | uniq -c | sort -rn | head -20
# 3) 单个可疑 IP 的请求顺序,看它第一个打的是什么
grep '203.0.113.9' access.log | awk '{print $4, $7}' | head -20
- 把这三条结果对照起来,通常能清楚看出入口是收录结果、外链页,还是别人泄露的清单。
Q:入口收敛之后,还需要拦截层吗?
- 需要,两者是先减少目标、再提高成本的关系,不能互相替代。
- 入口收敛解决「有多少爬虫知道你」:减少曝光面,让爬虫找上来更费劲。
- 拦截层解决「找到你之后能不能爬动」:频率限制、行为识别、UA 与 IP 封禁、验证码,都归这一层。
- 顺序建议是:先做能零成本收敛的(关目录浏览、拆 RSS 全文、给测试环境加鉴权),再补需要投入的(CDN 或 WAF 的爬虫规则、源站限速)。
- 只收敛不拦截,遇到定向爬虫照样被打;只拦截不收敛,每天都要处理新来的陌生爬虫。
Q:收敛入口会不会影响 SEO?
- 只要动作做在本来就该公开的页面之外,就不会影响收录,反而更健康。
- 三条判断标准可以直接套用:
- 该被收录的页面(栏目页、文章页、商品页)保持允许索引,sitemap 正常提交,不做任何限制。
- 不该被收录的页面(会员中心、购物车、筛选结果、分页过深的翻页)加
noindex,避免占用收录额度。 - 纯资源与订阅地址(RSS、附件、接口)不参与 SEO,关掉或限流都不影响排名。
- 反过来提醒一句:千万别用 UA 定向给出不同内容(对搜索引擎和普通用户返回不同页面),那属于作弊行为,风险远大于收益。
Q:还有什么补充建议?
- 把入口清单当成资产台账管:收录页、外链条数、订阅地址、开放目录、测试域名,各自登记一行,每次改版前复核一次。
- 先零成本、后投入:关目录浏览、拆 RSS 全文、测试环境加鉴权、清理问题友链,这四件事几乎不花钱,收益却最大。
- 用日志验证收敛效果:做完之后每周看一次 404 分布与新出现 IP 的首次访问路径,入口少了,陌生爬虫数量应该肉眼可见地下降。
- 子域名和旧域名别忘掉:遗留域名、老测试站、历史解析记录都是入口,定期用证书透明度日志和 DNS 历史自查一遍。
- 一句话总结:爬虫不是碰巧找到你的,它是顺着你铺的路走过来的——先关掉多余的门(目录浏览、订阅全文、裸奔的测试环境),再在必经之路上设卡(频率、行为、验证),顺序反了就是天天救火。