网站图片资源被爬虫大量抓取,不仅消耗服务器带宽,还可能影响正常用户访问速度。通过 Nginx 配置可以精准拦截爬虫对图片目录的请求,同时不影响搜索引擎正常收录。本教程将分步演示如何用 Nginx 实现图片防爬虫功能,并附带流量节省数据验证方法。
## 前置准备
1. **服务器环境**:已安装 Nginx 的 Linux 服务器(本教程基于 Ubuntu 20.04 + Nginx 1.18,其他版本操作一致)
2. **网站配置**:拥有网站 Nginx 配置文件编辑权限(通常位于 `/etc/nginx/sites-available/` 或 `/etc/nginx/conf.d/`)
3. **图片目录**:确定需要保护的图片存放路径(例如 `/var/www/html/images/` 或 `/wp-content/uploads/`)
4. **测试工具**:本地电脑安装 curl 命令(Windows 需安装 Git Bash 或 WSL),用于验证配置效果
5. **备份文件**:使用 `cp /etc/nginx/sites-available/your-site.conf /etc/nginx/sites-available/your-site.conf.bak` 备份原配置
## 分步操作步骤
### 1. 识别并拒绝已知爬虫 User-Agent
打开 Nginx 站点配置文件(假设文件名为 example.com.conf):
```bash
sudo nano /etc/nginx/sites-available/example.com.conf
```
在 `server` 块内添加以下内容(建议放在 `location` 块之前):
```nginx
# 禁止常见爬虫抓取图片
if ($http_user_agent ~* (python|curl|wget|scrapy|java|php|perl|ruby) ) {
set $block_ua 1;
}
```
保存文件后,执行语法检查:
```bash
sudo nginx -t
```
若输出 `syntax is ok`,继续执行重载:
```bash
sudo systemctl reload nginx
```
**验证方法**:使用模拟爬虫请求测试:
```bash
curl -A "python-requests/2.28" -I https://yourdomain.com/images/photo.jpg
```
返回 200 状态码说明配置未生效(需配合后续步骤)。此步骤仅标记变量,需结合图片 location 使用。
### 2. 配置图片目录的访问规则
在 `server` 块中找到处理图片的 `location` 指令(若没有则新建),典型配置如下:
```nginx
location ~* \.(jpg|jpeg|png|gif|webp|bmp|ico)$ {
# 允许正常访问
try_files $uri =404;
# 如果被标记为爬虫,返回 403 禁止访问
if ($block_ua) {
return 403;
}
# 设置缓存头(可选)
expires 30d;
add_header Cache-Control "public, immutable";
}
```
若图片存放在特定子目录(如 `/wp-content/uploads/`),使用更精确的匹配:
```nginx
location /wp-content/uploads/ {
location ~* \.(jpg|jpeg|png|gif|webp)$ {
if ($block_ua) {
return 403;
}
try_files $uri =404;
}
}
```
保存配置后执行 `sudo nginx -t` 和 `sudo systemctl reload nginx`。
### 3. 添加 Referer 防盗链(增强防护)
在图片 location 块内继续添加:
```nginx
location ~* \.(jpg|jpeg|png|gif|webp)$ {
# 允许空 Referer(用户直接访问图片)
valid_referers none blocked server_names
~\.yourdomain\.com
~\.google\.com
~\.baidu\.com;
if ($invalid_referer) {
return 403;
}
# 保留之前的爬虫检测
if ($block_ua) {
return 403;
}
try_files $uri =404;
}
```
**参数说明**:
- `none`:允许没有 Referer 的请求(直接打开图片链接)
- `blocked`:允许 Referer 被隐藏的请求
- `server_names`:允许本站域名
- `~\.yourdomain\.com`:正则匹配子域名
- `~\.google\.com` 和 `~\.baidu\.com`:允许搜索引擎正常抓取
### 4. 限制请求频率(针对高频爬虫)
在 `http` 块(通常位于 `/etc/nginx/nginx.conf`)中定义限流区域:
```nginx
http {
# 定义限流区域:每个 IP 每秒最多 5 个请求,突发 10 个
limit_req_zone $binary_remote_addr zone=img_limit:10m rate=5r/s;
# 其他配置保持不变
include /etc/nginx/conf.d/*.conf;
}
```
然后在图片 location 块中应用:
```nginx
location ~* \.(jpg|jpeg|png|gif|webp)$ {
# 应用限流,超过限制返回 503
limit_req zone=img_limit burst=10 nodelay;
# 其他规则(referer、ua检测等)
# ...
try_files $uri =404;
}
```
重载 Nginx 后,使用连续请求测试:
```bash
for i in {1..20}; do curl -I https://yourdomain.com/images/photo.jpg; done
```
观察第 11 个请求后是否出现 503 状态码。
### 5. 配置白名单放行正常爬虫
在 `server` 块顶部添加搜索引擎白名单:
```nginx
# 搜索引擎白名单
set $allow_crawler 0;
# 百度蜘蛛
if ($http_user_agent ~* (Baiduspider|Baiduspider-render|Baiduspider-image) ) {
set $allow_crawler 1;
}
# 谷歌蜘蛛
if ($http_user_agent ~* (Googlebot|Googlebot-Image) ) {
set $allow_crawler 1;
}
# 必应蜘蛛
if ($http_user_agent ~* (bingbot|msnbot) ) {
set $allow_crawler 1;
}
```
修改图片 location 块的判断逻辑:
```nginx
location ~* \.(jpg|jpeg|png|gif|webp)$ {
# 如果不是白名单爬虫,且匹配黑名单特征,则拦截
if ($allow_crawler = 0) {
if ($http_user_agent ~* (python|curl|wget|scrapy|java|php) ) {
return 403;
}
}
# 其他规则
# ...
}
```
### 6. 验证配置并监控流量变化
**验证配置完整性**:
```bash
sudo nginx -t
sudo systemctl reload nginx
```
**模拟正常用户访问**:
```bash
# 正常浏览器访问(应返回 200)
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" -I https://yourdomain.com/images/photo.jpg
# 模拟爬虫访问(应返回 403)
curl -A "python-requests/2.28" -I https://yourdomain.com/images/photo.jpg
# 模拟盗链(应返回 403)
curl -e "http://evil-site.com" -I https://yourdomain.com/images/photo.jpg
```
**查看 Nginx 访问日志**:
```bash
sudo tail -f /var/log/nginx/access.log | grep "images/photo.jpg"
```
被拦截的请求会显示 `403` 状态码。
**监控带宽节省**:使用 `iftop` 或 `vnstat` 工具对比配置前后流量:
```bash
# 安装 iftop
sudo apt install iftop
# 监控指定端口
sudo iftop -i eth0 -f "port 80 or port 443"
```
## 常见问题
**Q1:配置后网站图片加载不出来**
检查是否误拦截了正常用户。在浏览器中打开开发者工具(F12),查看 Network 标签页中图片请求的 Referer 和 User-Agent。若 Referer 为空,确认 `valid_referers` 中是否包含 `none` 参数。若 User-Agent 包含浏览器标识,检查白名单规则是否覆盖了主流浏览器。
**Q2:百度/谷歌图片搜索不收录图片**
确保 `valid_referers` 中包含搜索引擎域名(如 `~\.google\.com` 和 `~\.baidu\.com`),且 User-Agent 白名单中加入了对应的蜘蛛标识。配置后使用 Google Search Console 的“检查网址”功能测试图片 URL。
**Q3:配置后服务器报错“nginx: [emerg] unknown directive”**
检查是否在 `http` 块外使用了 `limit_req_zone` 指令,或 `if` 语句嵌套层级错误。确保所有指令都写在正确的上下文(`http`、`server`、`location`)中。
**Q4:部分爬虫仍然能访问图片**
爬虫可能伪造 User-Agent 或 Referer。建议结合 IP 黑名单(如 `deny 123.123.123.0/24;`)或使用第三方防护服务(如 Cloudflare 的 Bot Fight Mode)增强防护。
**Q5:配置后网站性能下降**
限流规则 `limit_req` 可能导致正常用户偶尔遇到 503。调整 `rate` 参数(如改为 `10r/s`)或增大 `burst` 值(如 `burst=20`)。同时确保 `limit_req_zone` 的内存大小(10m)足够容纳活跃 IP 数。
## 收尾总结
通过本教程的 6 个步骤,你已实现 Nginx 层面的图片防爬虫系统:
- **User-Agent 过滤**:拦截 python、curl 等常见爬虫工具
- **Referer 防盗链**:阻止外部网站直接引用图片
- **请求频率限制**:防止单个 IP 大量抓取
- **搜索引擎白名单**:确保百度、谷歌正常收录
建议在配置生效后持续观察 7 天服务器流量日志,使用 `awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20` 统计请求最多的 IP,针对异常 IP 可追加到 Nginx 黑名单。对于图片资源较多的网站,建议同时开启 Nginx 的 `gzip` 压缩和浏览器缓存(`expires` 指令),进一步降低带宽消耗。