网站如何禁止爬虫抓取图片资源|节省服务器流量(Nginx 配置教程)

发布时间:2026-07-23 16:42

网站图片资源被爬虫大量抓取,不仅消耗服务器带宽,还可能影响正常用户访问速度。通过 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` 指令),进一步降低带宽消耗。