用带宽限速脚本限制爬虫占用服务器流量,零基础实操教程
用带宽限速脚本限制爬虫占用服务器流量,零基础实操教程
不少站长发现,网站正常用户访问不多,但服务器带宽经常跑满。
查日志后会发现,大量流量来自搜索引擎爬虫、采集软件或恶意爬虫。
如果直接封禁IP,可能误封正常搜索爬虫影响收录。
更好的做法是用带宽限速脚本限制爬虫占用服务器流量,让爬虫爬得慢一点,但依然可用。
本文从零开始,教你写一个简单实用的限速脚本。
爬虫占满带宽的常见场景
- 搜索引擎爬虫(百度、谷歌)集中抓取新网站,并发过高
- 采集站或AI训练数据爬虫不断请求页面
- 恶意爬虫扫站、刷流量
如果不加限制,服务器带宽被占满后,真实用户访问会变慢甚至超时,严重时影响业务。
准备工作:确认你的服务器环境
在操作前,先确认以下条件:
- Linux系统(本文以CentOS 7/8、Ubuntu 20/22为例)
- 拥有root权限,或能执行sudo
- 已安装iptables或tc工具(大多数系统自带,未安装时执行
apt install iptables或yum install iptables-services) - 已确定爬虫的来源IP范围或User-Agent特征(可以先从日志中提取)
宝塔面板用户可直接在终端执行命令,或在计划任务中添加脚本。
编写带宽限速脚本(两种常用方案)
方案一:使用iptables + hashlimit 模块限速
iptables 的 hashlimit 模块可以根据源IP或目标端口限制数据包速率。
以下脚本限制每个源IP的HTTP(80端口)和HTTPS(443端口)速率不超过200Kbps(可以根据需要调整):
#!/bin/bash
# 限制爬虫使用服务器带宽 - iptables hashlimit版本
# 清空旧规则(谨慎使用,先备份现有规则)
# iptables -F
# 对HTTP/HTTPS流量做限速,每个源IP限制200Kbps,且突发不超过400Kbps
iptables -A INPUT -p tcp --dport 80 -m hashlimit --hashlimit-name http_limit --hashlimit-mode srcip --hashlimit-above 200kb/s --hashlimit-burst 400kb -j DROP
iptables -A INPUT -p tcp --dport 443 -m hashlimit --hashlimit-name https_limit --hashlimit-mode srcip --hashlimit-above 200kb/s --hashlimit-burst 400kb -j DROP
说明:--hashlimit-above 200kb/s表示超过该速率的数据包会被丢弃,从而实现带宽限制。--hashlimit-mode srcip表示以源IP为限制单位。如果爬虫并发高,超过速率就会丢包,爬虫自然会降低速度。
如果爬虫User-Agent特征明显(如 BadCrawler/1.0 ),还可以先用iptables匹配UA做标记,再限速,避免误限正常用户。
方案二:使用tc(traffic control)限速更精准
tc 可以对特定IP的带宽进行更精细的控制。
以下脚本限制单个IP的下载速度不超过300Kbps:
#!/bin/bash
# 使用tc限制单个IP带宽 - 爬虫限速
DEV=eth0 # 请替换为你的外网网卡名称(可用 ip a 查看)
LIMIT_IP="192.168.1.100" # 替换为目标爬虫IP,或写一个脚本循环多个IP
LIMIT_RATE="300kbps"
# 创建根队列规则
tc qdisc add dev $DEV root handle 1: htb default 30
tc class add dev $DEV parent 1: classid 1:1 htb rate 1000mbit
# 创建针对该IP的限速类
tc class add dev $DEV parent 1:1 classid 1:10 htb rate $LIMIT_RATE ceil $LIMIT_RATE
tc filter add dev $DEV protocol ip parent 1:0 prio 1 u32 match ip dst $LIMIT_IP flowid 1:10
如果想动态限速所有爬虫IP,可以写一个脚本读取nginx日志里请求频率高的IP,逐一执行上述限制。
建议自动执行
将脚本保存为 /root/limit_crawler.sh,
添加执行权限 chmod +x /root/limit_crawler.sh,
然后加入crontab定时执行,
例如每5分钟执行一次检查:
*/5 * * * * /root/limit_crawler.sh
避坑指南:别把正常用户也限了
- 不要盲目限速所有IP:先用日志分析哪些IP是爬虫。可以通过
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20查看请求最多的IP。 - 注意User-Agent:真正的搜索引擎爬虫UA通常固定(如
Baiduspider、Googlebot),可以用iptables的--u32或nginx map先做标记,仅对标记过的IP限速。 - 测试环境先试:在正式应用前,先在本机或测试服务器执行,然后用另一台机器模拟爬虫确认限速生效。
- 不要忘记放开自己的IP:如果你自己需要远程管理,记得把自己的IP加入白名单,否则可能把自己限速甚至断连。
验证限速效果
方法1:观察带宽占用
使用 iftop -i eth0 实时查看流量,能看到限速前爬虫峰值很高,限速后指定IP的带宽曲线下降到设定值以下。
方法2:检查iptables规则
iptables -L -n -v
查看限速匹配到的数据包数量,如果Packet计数持续增加,说明规则生效。
方法3:从爬虫角度测试
在另一台机器上用 curl --limit-rate 100M http://你的服务器IP 来模拟高速下载,看目标IP速度是否被压制。
常见问题(FAQ)
Q:限速后爬虫还会抓取吗?
A:会,但速度变慢。对搜索引擎爬虫来说,只要不超过其重试超时时间,通常不会影响收录。不过对于恶意采集,限速可以降低影响。
Q:iptables hashlimit会不会消耗太多CPU?
A:对于中小型网站(每日几百万请求),hashlimit开销很小。如果有海量IP并发,建议改用tc或nginx层面限速。
Q:宝塔面板有没有现成的限速功能?
A:宝塔Nginx防火墙的“CC防御”有速率限制,但针对的是请求次数,不是带宽。本文的脚本可以直接在宝塔的“计划任务”中添加,效果更直接。
如果你正在处理爬虫占用服务器流量的问题,建议先按本文步骤执行限速脚本,观察1-2天效果。
再结合日志微调限速阈值。
遇到异常时,优先回看避坑部分,确保没有误限正常用户。