如何处理使用站内搜索并因请求过多而溢出 SQL 的机器人?

How do deal with bots using the in-site search and overflowing the SQL with too many requests?

最好的做法是什么既不会用洪水限制惹恼用户,又能阻止机器人进行自动搜索?

发生了什么:

我更加了解奇怪的搜索行为,我终于有时间了解它是谁。它是 157.55.39.* 也称为 Bing。这很奇怪,因为当检测到 _GET['q'] 时,没有添加索引。

但是问题是,它们正在减慢 SQL 服务器的速度,因为传入的请求实例太多。

到目前为止我做了什么:

我已经实施了搜索洪水限制。但是因为我是用会话 cookie 做的,所以从上次搜索时间戳开始检查和计算——bing 显然忽略了 cookie 并继续。

最坏的情况是添加 reCAPTHA,但我不希望每次搜索时都出现 "Are you human?" 复选框。它应该只在检测到洪水时出现。所以基本上,真正的问题是,如何检测来自客户端的太多请求以触发某种重新验证来停止请求..

编辑#1:
我目前处理的情况是:

<?

# Get end IP
define('CLIENT_IP', (filter_var(@$_SERVER['HTTP_X_FORWARDED_IP'], FILTER_VALIDATE_IP) ? @$_SERVER['HTTP_X_FORWARDED_IP'] : (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP) ? @$_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'])));

# Detect BING:
if (substr(CLIENT_IP, 0, strrpos(CLIENT_IP, '.')) == '157.55.39') {

    # Tell them not right now:
    Header('HTTP/1.1 503 Service Temporarily Unavailable');

    # ..and block the request
    die();
}

有效。但这似乎是解决更系统问题的另一种临时解决方案。

我想提一下,我仍然想要搜索引擎,包括 Bing 索引 /search.html,只是不要在那里实际搜索。没有 "latest searches" 或类似的东西,所以他们从哪里获得查询是个谜。

编辑#2——我是如何解决的
如果以后其他人遇到这些问题,我希望这能有所帮助。

首先,事实证明 Bing 具有与 Google 相同的 URL 参数特征。所以我能够告诉 Bing 忽略 URL 参数 "q".

根据正确答案,我将参数 q 的禁止行添加到 robots.txt:

Disallow: /*?q=*
Disallow: /*?*q=*

我也在 bing 网站管理员控制台中告诉过,不要在高峰期打扰我们。

总的来说,这立即显示了服务器资源使用的积极反馈。但是,我将为相同的查询实施总体泛滥限制,特别是涉及 _GET 的地方。因此,如果 Bing 应该决定访问 AJAX 电话(例如:?action=upvote&postid=1)。

垃圾邮件是所有网站所有者都难以处理的问题。
并且有很多方法可以建立良好的保护,从非常简单的方法开始,到非常坚硬和强大的保护机制结束。

但现在我看到了一个简单的解决方案。
使用 robots.txt 并禁止 Bing 蜘蛛抓取您的搜索页面。
你可以这样做 very easy.

您的 robots.txt 文件如下所示:

User-agent: bingbot
Disallow: /search.html?q=

但这将完全阻止搜索引擎蜘蛛抓取您的搜索结果。
如果您只想限制此类请求,而不是完全阻止它们,请尝试以下操作:

User-agent: bingbot
crawl-delay: 10

这将强制 Bing 每 10 秒抓取一次您的网站页面。
但是这样的延迟,它每天只能抓取 8,640 个页面(这是非常小的请求量per/day)。
如果你擅长这个,那你就可以了。

但是,如果您希望通过服务器本身手动控制此行为,从而保护搜索表单免受网络爬虫和黑客的攻击怎么办?
他们可以轻松地向您的服务器发送超过 50,000 个请求 per/hour。

在这种情况下,我会向您推荐2种解决方案。
首先,将CloudFlare连接到您的网站,并且不要忘记通过ViewDNS IP History等服务检查您的服务器真实IP是否仍然可用,因为许多具有CF保护的网站缺乏这个(甚至流行过一次)。
如果您的活动服务器 IP 在历史记录中可见,那么您可以考虑更改它(强烈推荐)。

其次,你可以使用MemCached来存储洪水数据,并检测某个IP是否查询过多(即30 q/min)。
如果他们这样做,请阻止他们使用执行(通过 MemCached)一段时间。

当然,这不是您可以使用的最佳解决方案,但它可以工作并且对您的服务器来说成本不高。