打开访问日志,别只盯着404和500。内容被采集的痕迹,多半藏在那些正常的200响应里。日志里每一行通常有IP、时间、请求方法、URL、状态码、User-Agent、Referer和响应字节数,单看一条记录什么都看不出来,但把几十万条记录按维度一聚合,采集器的尾巴就露出来了。
先看访问频率和间隔。正常读者看文章,一次会话大概十几个请求,首页、列表页、详情页、图片、CSS、JS,间隔忽长忽短,看完就走。采集器不一样,它要成批拿内容,请求密、节奏稳。比如同一个IP一分钟请求八十次,每次间隔固定在两秒左右,UA写着python-requests/2.31.0,这种基本不用猜。也有采集器把间隔调到五秒、十秒,单看频率不算夸张,但它会连续几小时不停,而且只抓详情页,不碰静态资源。正常浏览器打开一篇文章,日志里会跟着出现图片和样式文件的请求;采集器只要HTML,同一IP的静态资源请求占比低得可怜,这个比例很能说明问题。
User-Agent是第二道筛子。空UA、curl、Go-http-client、Java、okhttp、Scrapy、headless Chrome,这些在正常用户日志里很少见。有些采集器会伪装成浏览器,但字段不全,版本号老得离谱,或者同一UA在几分钟内从几十个IP冒出来。搜索引擎蜘蛛的UA也常见,Baiduspider、Googlebot、bingbot,别急着封,先看它是否请求robots.txt、是否遵守爬取间隔、IP反查是不是官方段。采集器通常无视robots,或者请求了robots照样高频抓详情页。
请求路径和Referer也很直白。正常用户从列表页点进详情页,Referer有站内地址,URL分散,带参数也乱。采集器常按文章ID顺序翻,URL里的数字挨着递增,Referer为空或者统一指向同一个列表页。你把某个IP的URL按时间排一遍,发现它从ID 1001抓到1200,中间不跳、不停、不看分类,这不是人在读。还有采集器会带伪造Referer,但路径顺序骗不了人。
时间分布能补一刀。正常站点凌晨流量低,采集器可以24小时均匀跑,凌晨两点到五点的请求量反而占全天三成以上。我见过一个日志片段,某组IP在凌晨2点到5点请求了四千多次,全是详情页,UA集中在三个版本,静态资源一次没请求,这种组合基本能确定是采集。IP特征也别忽略,云服务器段、代理池、C段集中。把IP按C段聚合,几十个IP来自同一段,请求路径一模一样,UA也相同,那就是换IP接着抓。

实操不用太复杂。用awk按IP统计:awk ''{print $1}'' access.log | sort | uniq -c | sort -nr | head -30,先揪出请求量前几十的IP;再按UA统计:awk -F''"'' ''{print $6}'' access.log | sort | uniq -c | sort -nr | head,看有没有异常UA;按URL统计能看出哪些页面被反复抓。GoAccess、ELK也能做可视化,Excel透视表同样够用。关键是把频率、UA、路径、时间、静态资源比例放在一起看,单一指标容易误判,组合起来模式很清楚。
发现采集后,日志先留着,封高频IP段、限速、加验证码、给内容页加动态签名都行。但更重要的是养成每周翻日志的习惯,采集器不会提前打招呼,它只会在日志里留下一串规律得不像人的记录。