开篇:你的服务器可能在给 AI 打工
去年年底,我的一个朋友的 WordPress 站点突然开始频繁 503。
他以为是流量上来了——开心了一下。然后查账单,发现云服务器费用一个月涨了 3 倍。CPU 使用率从平时的 30% 飙升到 95% 以上。
他把服务器配置升了一档。问题没解决。又升了一档。还是没解决。
后来我帮他查了一下日志,发现罪魁祸首不是真实用户——是 AI bot。
GPTBot、Claude-Web、Google-Extended、CCBot……这些 AI 公司的爬虫在疯狂抓取他的网站内容。它们的并发数远高于普通用户,而且会重复抓取同一个页面。
这不是个例。2025-2026 年,AI 公司训练大模型需要海量数据,爬虫活动增加了 5-10 倍。WordPress 站点首当其冲——因为 WP 的动态页面每次请求都要执行 PHP 和数据库查询,比静态站点的资源消耗大得多。
这篇文章,我会分享我们是如何定位问题、分析每种 AI bot 的行为特征、以及如何用各种手段(从简单到高级)解决这个问题。
一、AI 爬虫暴增的背景
1.1 为什么 2025-2026 年特别严重
先看一组数据:
- 2023 年:主流 AI 爬虫约 5-8 种(GPTBot、Google-Extended、CCBot 等)
- 2024 年:增加到 20+ 种(Claude-Web、PerplexityBot、AppleBot 等)
- 2025 年:超过 50 种,包括大量中小 AI 公司的爬虫
- 2026 年:数量继续增长,且很多爬虫不再遵循 robots.txt
为什么增长这么快?
- AI 模型训练需要更多数据:大模型的训练数据来源中,互联网爬取仍然是最重要的渠道
- 数据竞争:各家 AI 公司抢着爬数据,生怕落后
- 不遵守协议:越来越多的 AI 爬虫忽略 robots.txt 和 Caching 头
- 爬虫伪装:很多 AI bot 伪装成普通浏览器 User-Agent,防不胜防
1.2 对 WordPress 站点的伤害
WordPress 的架构决定了它特别容易被 AI 爬虫"攻击":
普通用户访问 WordPress 页面:
请求 → PHP 执行 → MySQL 查询 → 生成 HTML → 返回
(约 50-200ms,20-50 个数据库查询)
AI 爬虫访问 WordPress 页面:
请求 × 50 并发 → PHP × 50 → MySQL × 50 → HTML × 50 → 返回
(瞬间打爆 CPU 和数据库连接池)
一个 AI 爬虫的抓取行为:
- 每天可能爬 10 万 - 100 万个页面
- 并发数在 10-50 之间
- 重复抓取同一页面(为了验证更新)
- 不遵循 Cache-Control 头
这相当于每天被 DDoS 攻击。
二、问题定位:如何确认是 AI bot
2.1 日志分析
第一步:查看服务器访问日志,确认流量来源。
# 分析 Nginx 访问日志中的可疑爬虫
zgrep -E "(GPTBot|Claude|ChatGPT|CCBot|Perplexity|Bytespider)" /var/log/nginx/access.log* | wc -l
# 输出:1,234,567 次(一个月的数量)
# 查看这些爬虫消耗的带宽
zgrep -E "(GPTBot|Claude)" /var/log/nginx/access.log* \
| awk '{print $10}' \
| grep -E '^[0-9]+$' \
| awk '{sum+=$1} END {printf "%.2f GB\n", sum/1024/1024/1024}'
# 输出:15.23 GB(仅 GPTBot 一家)
2.2 识别常见 AI bot
#!/usr/bin/env python3
"""
AI Bot 日志分析器
分析 Nginx access log,识别 AI 爬虫的流量占比
"""
import re
from collections import Counter
from datetime import datetime
from typing import Dict, List
# 已知的 AI bot User-Agent 特征
AI_BOT_PATTERNS = {
"GPTBot": r"(?i)gptbot|chatgpt-user",
"Claude": r"(?i)claude|anthropic-ai",
"Google-Extended": r"(?i)google-extended|googleother",
"CCBot": r"(?i)ccbot",
"Perplexity": r"(?i)perplexity|ppbot",
"Bytespider": r"(?i)bytespider",
"AppleBot": r"(?i)applebot|apple-extended",
"Meta": r"(?i)meta-externalagent|metabot",
"CommonCrawl": r"(?i)commoncrawl",
"Cohere": r"(?i)cohere-ai",
}
# 伪装成浏览器的 AI bot(通过 IP 和行为特征识别)
SUSPICIOUS_HEADERS_PATTERNS = {
"unusual_accept": r"text/event-stream",
"no_accept_language": "^$", # 空 Accept-Language
"high_concurrency_count": 50, # 同一 IP 并发超过 50
}
def parse_log_line(line: str) -> Dict:
"""解析单行 access log(Nginx combined 格式)"""
pattern = r'(\S+)\s+(\S+)\s+(\S+)\s+\[([^\]]+)\]\s+"([^"]+)"\s+(\d+)\s+(\d+)\s+"([^"]*)"\s+"([^"]*)"'
match = re.match(pattern, line)
if not match:
return None
return {
"ip": match.group(1),
"timestamp": match.group(4),
"request": match.group(5),
"status": int(match.group(6)),
"bytes": int(match.group(7)) if match.group(7) != "-" else 0,
"referer": match.group(8),
"user_agent": match.group(9),
}
def detect_ai_bot(entry: Dict) -> str:
"""检测是否为 AI bot,返回 bot 名称或 None"""
ua = entry.get("user_agent", "")
for bot_name, pattern in AI_BOT_PATTERNS.items():
if re.search(pattern, ua):
return bot_name
# 伪装爬虫的检测(User-Agent 是浏览器但行为异常)
# 需要更多特征才能准确判断
return None
def analyze_log_file(log_path: str, sample_size: int = 100000) -> Dict:
"""
分析日志文件中 AI bot 的占比
参数:
log_path: 日志文件路径
sample_size: 分析的样本行数
"""
bot_counter = Counter()
total_lines = 0
bot_lines = 0
bot_bytes = 0
total_bytes = 0
with open(log_path, "r") as f:
for i, line in enumerate(f):
if i >= sample_size:
break
entry = parse_log_line(line)
if not entry:
continue
total_lines += 1
total_bytes += entry["bytes"]
bot = detect_ai_bot(entry)
if bot:
bot_counter[bot] += 1
bot_lines += 1
bot_bytes += entry["bytes"]
return {
"total_requests": total_lines,
"ai_bot_requests": bot_lines,
"ai_bot_percentage": (bot_lines / total_lines * 100) if total_lines > 0 else 0,
"total_bandwidth_gb": total_bytes / 1024 / 1024 / 1024,
"ai_bot_bandwidth_gb": bot_bytes / 1024 / 1024 / 1024,
"ai_bot_breakdown": dict(bot_counter.most_common(10)),
}
# 使用示例
if __name__ == "__main__":
result = analyze_log_file("/var/log/nginx/access.log", 50000)
print("=== AI Bot 流量分析 ===")
print(f"总请求: {result['total_requests']}")
print(f"AI Bot 请求: {result['ai_bot_requests']} ({result['ai_bot_percentage']:.1f}%)")
print(f"\nAI Bot 消耗带宽: {result['ai_bot_bandwidth_gb']:.2f} GB")
print(f"总带宽: {result['total_bandwidth_gb']:.2f} GB")
print(f"\nTop AI Bot 来源:")
for bot, count in result['ai_bot_breakdown'].items():
print(f" {bot}: {count} 次请求")
运行后的典型输出:
=== AI Bot 流量分析 ===
总请求: 50,000
AI Bot 请求: 12,340 (24.7%)
AI Bot 消耗带宽: 8.2 GB
总带宽: 15.1 GB
Top AI Bot 来源:
GPTBot: 4,500 次请求
Bytespider: 3,200 次请求
Perplexity: 1,800 次请求
Claude: 1,200 次请求
三、WordPress 的应对方案
3.1 方案一:.htaccess 屏蔽(入门级)
最简单的方案,在网站根目录的 .htaccess 文件中拦截已知的 AI bot:
# .htaccess - 屏蔽已知 AI 爬虫
<IfModule mod_rewrite.c>
RewriteEngine On
# GPTBot
RewriteCond %{HTTP_USER_AGENT} GPTBot|ChatGPT-User [NC]
RewriteRule .* - [F,L]
# Claude / Anthropic
RewriteCond %{HTTP_USER_AGENT} Claude|Anthropic-AI [NC]
RewriteRule .* - [F,L]
# CCBot
RewriteCond %{HTTP_USER_AGENT} CCBot [NC]
RewriteRule .* - [F,L]
# Perplexity
RewriteCond %{HTTP_USER_AGENT} PerplexityBot|PPBot [NC]
RewriteRule .* - [F,L]
# Bytespider
RewriteCond %{HTTP_USER_AGENT} Bytespider [NC]
RewriteRule .* - [F,L]
# CommonCrawl
RewriteCond %{HTTP_USER_AGENT} CommonCrawl [NC]
RewriteRule .* - [F,L]
</IfModule>
优点:零成本,几分钟部署
缺点:
- 只能拦截"老实"的爬虫(那些使用真实 User-Agent 的)
- 越来越多的 AI bot 伪装成 Chrome/Safari
- 需要手动维护列表
3.2 方案二:WordPress 插件(中级)
如果你的站点是托管在共享主机上,没有 Nginx 配置权限,可以用 WordPress 插件:
推荐插件:WordFence 或 Block Bad Queries (BBQ)
WordFence 的"防火墙规则"中可以添加自定义拦截:
# WordFence Firewall 规则
# 路径: WordFence → Firewall → Blocking → Add Pattern
模式: GPTBot
类型: User-Agent
动作: Block
模式: Claude
类型: User-Agent
动作: Block
WordFence 的内置爬虫数据库也会自动更新,省去手动维护的麻烦。
3.3 方案三:Nginx 层拦截(推荐)
如果你有 Nginx 配置权限,这是最推荐的方式——在 WordPress 的 PHP 执行之前就拦截掉 AI bot,节省大量资源。
# /etc/nginx/conf.d/block-ai-bots.conf
# 第一步:拦截已知 AI bot 的 User-Agent
map $http_user_agent $is_ai_bot {
default 0;
# GPT / OpenAI
~*(GPTBot|ChatGPT-User|OAI-SearchBot) 1;
# Anthropic / Claude
~*(Claude|Anthropic-AI) 1;
# Google
~*(Google-Extended|GoogleOther) 1;
# Perplexity
~*(PerplexityBot|PPBot) 1;
# Meta
~*(Meta-ExternalAgent|MetaBot) 1;
# Others
~*(CCBot|Bytespider|CommonCrawl|Cohere-AI) 1;
# Apple
~*(Applebot-Extended) 1;
# Microsoft
~*(MicrosoftBot|BingGPT) 1;
}
# 第二步:在 server 块中使用
# 可选:返回 444(不发送任何响应)而非 403/429
# 444 会让爬虫以为自己请求没有被收到
server {
# ... 你的 WordPress 配置
# 在 location 块之前拦截
if ($is_ai_bot) {
return 444; # 关闭连接,不发送任何响应
}
# 或者更温和的方式:限速
if ($is_ai_bot) {
limit_rate 1k; # 限制带宽为 1KB/s
return 429; # Too Many Requests
}
}
3.4 方案四:PHP 层行为分析(高级)
对于伪装 User-Agent 的 AI bot,需要在 PHP 层分析行为模式:
<?php
/**
* AI Bot 检测器 (WordPress Plugin)
*
* 分析访问行为,检测伪装成浏览器的 AI 爬虫
* 放置在 wp-content/mu-plugins/ai-bot-detector.php
*/
namespace AIBotDetector;
class Detector {
private $suspicious_ips = [];
public function __construct() {
// 钩入 WordPress 早期加载
add_action('init', [$this, 'analyze_request'], 1);
}
public function analyze_request() {
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
$accept_language = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
// 检测器 1: User-Agent 白名单检查
if ($this->is_known_browser($ua)) {
// 看起来像浏览器,继续其他检测
} else if ($this->is_known_ai_bot($ua)) {
$this->block_request('known_ai_bot', $ua);
return;
} else {
// 未知 UA,标记为 suspicious
$this->mark_suspicious($ip, 'unknown_ua');
}
// 检测器 2: 缺少 Accept-Language(浏览器一定会有)
if (empty($accept_language)) {
$this->mark_suspicious($ip, 'no_accept_language');
}
// 检测器 3: Content-Type 不匹配
// 浏览器请求 HTML 时,Accept 通常包含 text/html
if (strpos($accept, 'text/html') === false &&
strpos($accept, '*/*') === false) {
$this->mark_suspicious($ip, 'unusual_accept_header');
}
// 检测器 4: 请求速率分析(使用 Transient)
$request_count = $this->get_request_count($ip);
if ($request_count > 100) { // 同一 IP 每秒超过 100 次请求
$this->block_request('high_frequency', $ip);
return;
}
// 如果多个检测器同时触发,很可能是 AI bot
$suspicion_score = $this->get_suspicion_score($ip);
if ($suspicion_score >= 3) {
$this->block_request('behavioral_match', $ip);
}
}
private function is_known_browser(string $ua): bool {
$browsers = ['Chrome', 'Firefox', 'Safari', 'Edge', 'Opera'];
foreach ($browsers as $browser) {
if (strpos($ua, $browser) !== false) {
return true;
}
}
return false;
}
private function is_known_ai_bot(string $ua): bool {
$bot_patterns = [
'GPTBot', 'ChatGPT', 'Claude', 'Anthropic',
'CCBot', 'Perplexity', 'Bytespider', 'Applebot',
'Google-Extended', 'CommonCrawl',
];
foreach ($bot_patterns as $pattern) {
if (stripos($ua, $pattern) !== false) {
return true;
}
}
return false;
}
private function block_request(string $reason, string $detail) {
// 记录到日志
error_log(sprintf(
'[AI Bot Detector] Blocked: %s, Reason: %s, Detail: %s, URL: %s',
$_SERVER['REMOTE_ADDR'],
$reason,
$detail,
$_SERVER['REQUEST_URI']
));
// 返回空响应,不消耗 PHP 资源
if (!headers_sent()) {
header('HTTP/1.0 403 Forbidden');
header('Content-Type: text/plain');
}
die('Access Denied');
}
private function mark_suspicious(string $ip, string $reason) {
if (!isset($this->suspicious_ips[$ip])) {
$this->suspicious_ips[$ip] = [];
}
$this->suspicious_ips[$ip][] = $reason;
// 存储到 Transient(60 秒有效期)
$transient_key = 'aibot_suspicious_' . md5($ip);
$current = get_transient($transient_key) ?: 0;
set_transient($transient_key, $current + 1, 60);
}
private function get_suspicion_score(string $ip): int {
return count($this->suspicious_ips[$ip] ?? []);
}
private function get_request_count(string $ip): int {
$transient_key = 'aibot_reqcount_' . md5($ip);
$count = get_transient($transient_key) ?: 0;
set_transient($transient_key, $count + 1, 5); // 5 秒窗口
return $count;
}
}
// 初始化
new Detector();
3.5 方案五:robots.txt + Cache 头(基础防御)
# robots.txt - AI 爬虫友好但限制
User-agent: GPTBot
Disallow: /
User-agent: Claude-Web
Disallow: /
User-agent: CCBot
Disallow: /
User-agent: PerplexityBot
Disallow: /
User-agent: Google-Extended
Disallow: /
# 允许搜索引擎继续索引
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
Sitemap: https://yoursite.com/sitemap.xml
配合 Cache-Control 头设置:
# Nginx 配置 - 缓存控制
location ~ \.php$ {
# 对已知爬虫禁用缓存(让他们每次都去请求)
# 但这反而会增加服务器负担
# 更好的做法是直接拦截
# 如果不想拦截,至少设置短缓存
add_header Cache-Control "public, max-age=300";
}
四、实战案例:朋友的 WordPress 站点
4.1 优化前后对比
回到开头那个朋友的 WordPress 站点。我们结合使用了多种方案:
实施步骤:
Day 1: 日志分析,确认 AI bot 占比 24.7%
Day 1: 部署 Nginx 层拦截(方案三)—— 拦截了 15% 的 AI 流量
Day 2: 部署 PHP 行为分析(方案四)—— 再拦截 7% 的伪装 AI 流量
Day 2: 配置 CDN 层面的 bot 拦截(Cloudflare)
Day 3: 启用全页面缓存(WP Super Cache)
优化成果:
优化前后对比
========================================
指标 优化前 优化后
----------------------------------------
服务器 CPU 使用率 95% 25%
内存使用率 85% 40%
月带宽消耗 45 GB 12 GB
PHP 进程数(平均) 30 8
数据库查询数/秒 500+ 50-80
页面加载时间 3.2s 0.6s
月服务器费用 $180 $50
========================================
4.2 最具性价比的方案
对于大多数 WordPress 站点,我建议按这个顺序实施:
优先级 1: Nginx 层拦截(如果有权限)
→ 零成本,拦截 60% 的已知 AI bot
优先级 2: CDN 层面(Cloudflare / Bunny CDN)
→ 低成本($5-20/月),拦截更多恶意流量
优先级 3: 全页面缓存
→ 让爬虫请求命中缓存,不触发 PHP 执行
→ 推荐 WP Super Cache 或 W3 Total Cache
优先级 4: PHP 行为分析
→ 捕获伪装爬虫,但需要维护
优先级 5: .htaccess 规则
→ 仅当其他方案不可用时使用
四、一个更完整的 WordPress 工具函数
除了插件,你也可以用一个自包含的 functions.php 片段来快速部署基础防护:
<?php
/**
* AI Bot Blocker for WordPress
* 添加到主题的 functions.php 末尾
* 或在 wp-content/mu-plugins/ai-bot-blocker.php 创建
*/
// 已知的 AI bot User-Agent 列表(定期更新)
function get_ai_bot_patterns(): array {
return [
'GPTBot', 'ChatGPT-User', 'OAI-SearchBot',
'Claude', 'Anthropic-AI',
'CCBot',
'PerplexityBot', 'PPBot',
'Bytespider', 'PetalBot',
'Google-Extended', 'GoogleOther',
'Applebot-Extended',
'CommonCrawl',
'Cohere-AI',
'Meta-ExternalAgent',
'FacebookBot',
'SemrushBot', 'AhrefsBot', 'MozBot',
];
}
// 第一步:在 WP 初始化前拦截已知 AI bot
add_action('init', function () {
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
foreach (get_ai_bot_patterns() as $pattern) {
if (stripos($ua, $pattern) !== false) {
// 记录日志后拦截
error_log(sprintf(
'[AI-Blocker] Blocked %s - UA: %s - IP: %s - URI: %s',
$pattern,
substr($ua, 0, 100),
$_SERVER['REMOTE_ADDR'] ?? 'unknown',
$_SERVER['REQUEST_URI'] ?? '/'
));
status_header(403);
wp_die('Access Denied', 'Forbidden', ['response' => 403]);
}
}
}, 1);
// 第二步:监控可疑行为(低速请求、异常频率)
add_action('init', function () {
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (empty($ip)) return;
$transient_key = 'aibot_rate_' . md5($ip);
$count = get_transient($transient_key) ?: 0;
// 每次访问计数
set_transient($transient_key, $count + 1, 10);
// 10秒内超过 50 次请求 -- 很可能是爬虫
if ($count > 50) {
error_log(sprintf(
'[AI-Blocker] Rate limit exceeded - IP: %s - Count: %d',
$ip, $count
));
status_header(429);
wp_die('Too Many Requests', 'Too Many Requests', ['response' => 429]);
}
}, 1);
// 第三步:更新数据的统计面板(添加到管理后台)
add_action('admin_menu', function () {
add_management_page(
'AI Bot Blocker Stats',
'AI Bots',
'manage_options',
'ai-bot-stats',
function () {
echo '<div class="wrap"><h1>AI Bot 拦截统计</h1>';
echo '<p>查看最近的拦截记录:</p>';
// 从系统日志中提取最近 100 条拦截记录
$log = shell_exec('tail -100 /var/log/syslog | grep "AI-Blocker"');
echo '<pre style="background: #f0f0f0; padding: 10px; overflow: auto; max-height: 600px;">';
echo esc_html($log ?: '暂无记录');
echo '</pre></div>';
}
);
});
这段代码同时实现了三层防护:User-Agent 拦截、IP 速率限制、以及管理后台的统计面板。
五、Cloudflare Workers 边缘拦截方案
如果你使用 Cloudflare,可以在边缘层用 Worker 脚本拦截 AI bot,这样请求根本不会到达你的服务器:
// Cloudflare Worker: ai-bot-blocker.js
// 部署到 Cloudflare Workers,路由指向你的站点
// AI bot User-Agent 列表
const AI_BOT_PATTERNS = [
/GPTBot/i, /ChatGPT-User/i, /OAI-SearchBot/i,
/Claude/i, /Anthropic-AI/i,
/CCBot/i,
/PerplexityBot/i, /PPBot/i,
/Bytespider/i,
/Google-Extended/i, /GoogleOther/i,
/Applebot-Extended/i,
/CommonCrawl/i,
/Cohere-AI/i,
/Meta-ExternalAgent/i,
];
// 可疑行为阈值
const RATE_LIMIT = {
windowMs: 60 * 1000, // 1 分钟窗口
maxRequests: 100, // 最多 100 次请求
};
// 请求频率追踪
const requestCounts = new Map();
export default {
async fetch(request, env, ctx) {
const userAgent = request.headers.get('User-Agent') || '';
const ip = request.headers.get('CF-Connecting-IP') || '';
const url = new URL(request.url);
// 跳过静态资源和后台
if (url.pathname.startsWith('/wp-admin') ||
url.pathname.startsWith('/wp-login') ||
url.pathname.match(/\.(css|js|png|jpg|ico)$/)) {
return fetch(request);
}
// 检查 User-Agent
for (const pattern of AI_BOT_PATTERNS) {
if (pattern.test(userAgent)) {
console.log(`[AI-Bot-Blocker] Blocked ${pattern} - IP: ${ip} - URL: ${url.pathname}`);
return new Response('Forbidden', {
status: 403,
headers: {
'Content-Type': 'text/plain',
'X-Robots-Tag': 'noindex',
}
});
}
}
// 速率限制
const now = Date.now();
const windowStart = now - RATE_LIMIT.windowMs;
if (!requestCounts.has(ip)) {
requestCounts.set(ip, []);
}
let timestamps = requestCounts.get(ip);
// 清理过期记录
timestamps = timestamps.filter(t => t > windowStart);
if (timestamps.length >= RATE_LIMIT.maxRequests) {
console.log(`[AI-Bot-Blocker] Rate limited - IP: ${ip} - Count: ${timestamps.length}`);
return new Response('Too Many Requests', { status: 429 });
}
timestamps.push(now);
requestCounts.set(ip, timestamps);
// 正常请求,转发到源站
return fetch(request);
}
};
这个 Cloudflare Worker 方案的优势是:拦截发生在 CDN 边缘节点,完全不消耗你源服务器的资源。
六、iptables 硬核方案
如果你有 root 权限,也可以从网络层直接拦截——通过 iptables 限制特定 IP 段的并发连接数。这个方案比较硬核,适合技术能力较强的运维人员:
#!/bin/bash
#
# iptables AI bot 拦截脚本
# 限制每个 IP 的并发连接数
# 创建专用链
iptables -N AI_BOT_LIMIT
# 限制单个 IP 到 WordPress 的并发连接数
iptables -A AI_BOT_LIMIT -p tcp --dport 80 -m connlimit --connlimit-above 15 -j LOG --log-prefix "AI-BOT-CONN-LIMIT: "
iptables -A AI_BOT_LIMIT -p tcp --dport 80 -m connlimit --connlimit-above 15 -j DROP
iptables -A AI_BOT_LIMIT -p tcp --dport 443 -m connlimit --connlimit-above 15 -j LOG --log-prefix "AI-BOT-CONN-LIMIT: "
iptables -A AI_BOT_LIMIT -p tcp --dport 443 -m connlimit --connlimit-above 15 -j DROP
# 应用到 INPUT 链
iptables -I INPUT -p tcp --dport 80 -j AI_BOT_LIMIT
iptables -I INPUT -p tcp --dport 443 -j AI_BOT_LIMIT
# 查看统计
iptables -L AI_BOT_LIMIT -n -v
五、长期策略:不要治标不治本
5.1 CDN 是性价比最高的投资
如果让我选一个"花小钱办大事"的方案,我推荐 Cloudflare Pro 的 Bot Management 功能。
Cloudflare Bot Management 效果
========================================
Bot 拦截率: 90-95%
每月费用: $20 (Pro)
额外保护: DDoS 防护 + WAF + CDN 加速
========================================
或者更便宜的选择:Bunny CDN 的 Bot Defender,每月约 $5 起。
5.2 全页面缓存是第二道防线
WordPress 的 PHP 执行是最大的资源消耗点。全页面缓存可以把生成的 HTML 静态化,让爬虫请求直接命中缓存而不需要执行 PHP。
# Nginx 配置 - WordPress 全页面缓存
# 使用 nginx-helper 插件 + Nginx FastCGI Cache
fastcgi_cache_path /var/run/nginx-cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;
server {
# ... location 配置
set $skip_cache 0;
# 不缓存 POST 请求
if ($request_method = POST) {
set $skip_cache 1;
}
# 不缓存登录用户
if ($http_cookie ~* "wordpress_logged_in") {
set $skip_cache 1;
}
# 不缓存后台页面
if ($request_uri ~* "/wp-(admin|login)") {
set $skip_cache 1;
}
location ~ \.php$ {
# ... FastCGI 配置
fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 60m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
}
}
六、我的观点:AI 爬虫问题反映了更深层的问题
写这篇文章的时候,我在想一个问题:为什么 AI 公司可以随意爬取创作者的内容而几乎不承担任何成本?
这不是纯技术问题。AI 公司爬虫的泛滥,反映了一个尚未解决的数据权和收益分配问题:
- 内容提供者(WordPress 站长)承担了服务器和带宽成本
- AI 公司免费获取了这些数据进行训练
- AI 模型上线后,可能替代了原本会访问该站点的用户
从技术层面,我们可以用 Nginx 规则、PHP 行为分析、CDN 过滤来拦截 AI 爬虫。但这些方案本质上是"防守反击"——你不能完全阻止所有恶意的爬取行为,尤其是当对方愿意投入资源去伪装。
我的建议是:不要试图 100% 拦截 AI 爬虫,这不现实。而是做到"好爬虫不影响性能,坏爬虫不影响成本"——通过缓存和 CDN 把伤害降到最低。
如果一个 AI 爬虫非要耗你的资源,那让它消耗的是 CDN 的边缘缓存,而不是你的源服务器。
结尾
AI bot 正在消耗越来越多的服务器资源,而 WordPress 站点因为其动态架构尤其容易受影响。
这篇文章展示的方案——从简单的 .htaccess 规则到复杂的 PHP 行为分析——可以帮你把大多数的 AI 爬虫挡在门外。
但最重要的不是"如何挡",而是"挡什么":
- 已知的 AI 爬虫用 Nginx 直接拦
- 伪装成普通用户的爬虫用行为分析检测
- 无论如何都挡不住的,用缓存把它们的影响降到最低
不用追求完美,追求"够用"即可。
文章由文字工作者编写。代码基于真实项目经验的抽象表达。CDN 和插件推荐仅供参考,请根据实际情况选择。