Facebook 爬虫严重攻击我的服务器并忽略指令。多次访问相同资源

2024-05-06

Facebook 爬虫每秒多次访问我的服务器,它似乎忽略了 Expires 标头和 og:ttl 属性。

在某些情况下,它会在 1-5 分钟内多次访问同一 og:image 资源。在一个示例中,爬虫程序在 3 分钟内使用 12 个不同的 IP 地址访问同一张图像 12 次。

我只需要记录请求 10 分钟就发现了以下示例:

一张图片的时间和爬虫IP地址列表:

2018-03-30 15:12:58 - 66.220.156.145
2018-03-30 15:13:13 - 66.220.152.7
2018-03-30 15:12:59 - 66.220.152.100
2018-03-30 15:12:18 - 66.220.155.248
2018-03-30 15:12:59 - 173.252.124.29
2018-03-30 15:12:15 - 173.252.114.118
2018-03-30 15:12:42 - 173.252.85.205
2018-03-30 15:13:01 - 173.252.84.117
2018-03-30 15:12:40 - 66.220.148.100
2018-03-30 15:13:10 - 66.220.148.169
2018-03-30 15:15:16 - 173.252.99.50
2018-03-30 15:14:50 - 69.171.225.134

og:image 是根据什么Facebook 的文档 https://developers.facebook.com/docs/sharing/webmasters#markup:

当有人将内容分享到时显示的图像的 URL Facebook。请参阅下文了解更多信息,并查看我们的最佳实践 了解如何指定高质量预览图像的指南。

我在 og:image 中使用的图像的 Expires 标头设置为未来 +7 天。最近,我将其更改为未来+1年。这两种设置似乎都没有任何区别。爬虫似乎忽略的标头:

Cache-Control: max-age=604800
Content-Length: 31048
Content-Type: image/jpeg
Date: Fri, 30 Mar 2018 15:56:47 GMT
Expires: Sat, 30 Mar 2019 15:56:47 GMT
Pragma: public
Server: nginx/1.4.6 (Ubuntu)
Transfer-Encoding: chunked
X-Powered-By: PHP/5.5.9-1ubuntu4.23

根据脸书的对象属性文档 https://developers.facebook.com/docs/sharing/opengraph/object-properties, og:ttl 属性为:

距离重新抓取此页面还有几秒。用它来限制速率 Facebook 内容爬虫。允许的最小值为 345600 秒(4 天);如果您设置较低的值,则将使用最小值。 如果不包含此标签,则 ttl 将根据 您的网络服务器返回“Expires”标头,否则它将 默认为 7 天。

我已将此 og:ttl 属性设置为 2419200,即未来 28 天。

我一直想使用这样的东西:

header("HTTP/1.1 304 Not Modified"); 
exit;

但我担心 Facebook 的爬虫会忽略标题并将图像标记为已损坏 - 从而从共享故事中删除图像预览。

来自爬虫的这些请求正在传入。

有没有办法阻止爬虫这么快回来访问这些资源呢?

显示我的开放图和元属性的示例代码:

<meta property="fb:app_id" content="MyAppId" />
<meta property="og:locale" content="en_GB" />
<meta property="og:type" content="website" />
<meta property="og:title" content="My title" />
<meta property="og:description" content="My description" />
<meta property="og:url" content="http://example.com/index.php?id=1234" />
<link rel="canonical" href="http://example.com/index.php?id=1234" />
<meta property="og:site_name" content="My Site Name" />
<meta property="og:image" content="http://fb.example.com/img/image.php?id=123790824792439jikfio09248384790283940829044" />
<meta property="og:image:width" content="940"/>
<meta property="og:image:height" content="491"/>
<meta property="og:ttl" content="2419200" />

在我尝试了几乎所有其他的缓存、标头等等之后,唯一能将我们的服务器从“过于热​​情”的 Facebook 爬虫中拯救出来的东西(用户代理facebookexternalhit) was 只是拒绝访问并发回HTTP/1.1 429 Too Many RequestsHTTP响应,当爬虫“爬行太多”时。

诚然,我们有数千张图像希望爬虫程序抓取,但 Facebook 爬虫程序实际上对我们的服务器进行 DDOS收到数以万计的请求(是的,一遍又一遍相同的网址), 每小时。我记得是每小时 40 000 个请求使用 te 从不同 Facebook 的 IP 地址facebookexternalhit用户代理在某一时刻。

我们不想完全阻止爬虫,并且通过 IP 地址阻止也不是一个选择。我们只需要 FB 爬虫(相当)后退一点即可。

这是我们用来执行此操作的一段 PHP 代码:

.../图像/index.php

<?php

// Number of requests permitted for facebook crawler per second.
const FACEBOOK_REQUEST_THROTTLE = 5;
const FACEBOOK_REQUESTS_JAR = __DIR__ . '/.fb_requests';
const FACEBOOK_REQUESTS_LOCK = __DIR__ . '/.fb_requests.lock';

function handle_lock($lockfile) {
    flock(fopen($lockfile, 'w'), LOCK_EX);
}

$ua = $_SERVER['HTTP_USER_AGENT'] ?? false;
if ($ua && strpos($ua, 'facebookexternalhit') !== false) {

    handle_lock(FACEBOOK_REQUESTS_LOCK);

    $jar = @file(FACEBOOK_REQUESTS_JAR);
    $currentTime = time();
    $timestamp = $jar[0] ?? time();
    $count = $jar[1] ?? 0;

    if ($timestamp == $currentTime) {
        $count++;
    } else {
        $count = 0;
    }

    file_put_contents(FACEBOOK_REQUESTS_JAR, "$currentTime\n$count");

    if ($count >= FACEBOOK_REQUEST_THROTTLE) {
        header("HTTP/1.1 429 Too Many Requests", true, 429);
        header("Retry-After: 60");
        die;
    }

}

// Everything under this comment happens only if the request is "legit". 

$filePath = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['REQUEST_URI'];
if (is_readable($filePath)) {
    header("Content-Type: image/png");
    readfile($filePath);
}

您还需要配置重写,以将所有针对您的图像的请求传递给此 PHP 脚本:

.../图像/.htaccess (如果您使用的是 Apache)

RewriteEngine On
RewriteRule .* index.php [L] 

爬虫似乎“理解了这种”方法并且有效降低了尝试率 from 成千上万每小时请求数数百/数千每小时请求数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Facebook 爬虫严重攻击我的服务器并忽略指令。多次访问相同资源 的相关文章

  • 如何仅删除页面的自动段落格式,而不删除帖子的自动段落格式(WordPress)

    我已经熟悉这个在 WordPress 中删除自动段落格式的小技巧 remove filter the content wpautop remove filter the excerpt wpautop 但是添加这个函数 php删除整个网站的
  • PHP:将多字节字符串(单词)拆分为单独的字符

    尝试使用 mb split 将这个字符串 主楼怎么走 分割成单独的字符 我需要一个数组 但没有成功 有什么建议吗 谢谢你 例如 尝试使用带有 u 选项的正则表达式 chars preg split u string 1 PREG SPLIT
  • file_get_contents 大文件上传

    我正在尝试使用 fsockopen 上传 2GB 以上的大文件 但 file get content 出现以下错误 我无法在内存中存储大文件 我需要分块发送数据 但不知道如何执行此操作 请问有人可以指导我吗 致命错误 允许的内存大小 134
  • 解析错误:语法错误,意外的 T_RETURN [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 遇到这个问
  • php基于onclick函数输入日期类型

    用户选择日期 月份和年份 然后按一个按钮 根据他选择的日期向他显示数据库的值 不知道代码问题出在哪里
  • 将查询字符串附加到任何形式的 URL

    我要求用户在文本框中输入 URL 并需要向其附加查询字符串 URL 的可能值如下 http www example com http www example com http www example com a http www examp
  • PHP 的脚手架 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 PHP 中有什么东西可以像 Rails 一样创建基本的脚手架吗 编辑 我需要一些东西来快速原型化 一些框架比如Symfony http www sym
  • 为什么我的 Github 托管网站响应 HTTP 302 而不是 200?

    我拥有该域名penkov id au http penkov id au 我主持一个blog http michael penkov id au blog 2014 01 02 reinventing the wheel html usin
  • Cakedc.users => 总是重定向到主页

    我在新的 Cakephp 安装上使用插件 CakeDC Users 我有两个控制器 PagesController php CardsController php Pages 有 1 个操作 Beta 它是主页 Cards 有两个操作 索引
  • 将IP保存到数据库中

    当用户登录时 我想将他们的 IP 保存在数据库中 我该怎么做呢 MySQL 字段最适合使用哪种类型 获取IP的PHP代码是什么样的 我正在考虑将其用作登录 会话内容的额外安全功能 我正在考虑使用用户现在拥有的 IP 检查用户从数据库登录的
  • 设置从 Facebook 登录获取用户电子邮件 ID 的权限

    我在用着Facebook 3 0 SDK对于安卓 我必须实施Facebook登录 我正在访问用户的基本信息 例如姓名 用户 ID 但我也想访问用户的电子邮件 我浏览了很多博客和论坛 但不知道该怎么做 我正在使用我自己的 android 按钮
  • 从 php 执行 bash 脚本并立即输出回网页

    我有一组 bash 和 Perl 脚本 开发在 Linux Box 上部署所需的目录结构 可选 从svn导出代码 从这个源构建一个包 这在终端上运行良好 现在 我的客户请求此流程的 Web 界面 例如 某些页面上的 创建新包 按钮将一一调用
  • Laravel 登录后重定向回来

    登录后如何重定向返回页面 在 Laravel 5 2 中 认证控制器 protected redirectTo 重定向用户
  • php oracle客户端oci8安装出现什么问题

    我尝试了安装 PHP Oracle 客户端的所有过程 1 我安装了客户端版本8和32位 2 我在php ini中取消了oci的注释 3 重新启动Wamp 4 不确定是否真的安装 但我在 php ini 中得到了引用 5 但仍然无法连接 泰汉
  • PHP Intl 扩展线程安全吗?

    我一直在阅读有关 PHP 中的语言环境的内容 看起来setlocale 线程有问题 我对线程不太熟悉 文档提到它不是线程安全的 我想让我的项目能够处理某些数字格式 并且 Intl 扩展似乎很有趣 http php net manual en
  • php date_parse("2010 年 2 月") 给出日期 == 1

    当没有日期时 我将其称为 date parse 中的错误 d date parse Feb 2010 会给 d day 1 请参阅对此的评论date parse 手册页 http php net manual en function dat
  • PHP LDAP 查询获取特定安全组的成员

    我正在努力让 LDAP 查询工作来为我提供安全组的成员 我们的活动目录结构设置为 DC domain DC co dc uk然后 我们有一个名为 公司用户 的 OU 其中有一个用于 IT 和标准的 OU 在这些中我们创建了用户 所以我被设置
  • 设置大型电子邮件通知系统有哪些方法?

    我的公司有一个用 PHP 构建的网站 我们使用内置的 PHP 电子邮件功能每天向订阅者发送数千封电子邮件 这是一个糟糕的主意 它堵塞了我们的服务器 并且需要几个小时才能完成整个批次 现在我已经研究过像 MailChimp 这样的群发邮件服务
  • if/else 简写来定义变量

    我很难理解 if else 的 php 简写是如何描述的here https stackoverflow com questions 20233207 php if shorthand and echo in one line possib
  • 禁用 WooCommerce 手动/编辑订单的电子邮件通知

    需要 WooCommerce 专业知识 我需要禁用手动创建的订单的电子邮件通知 我必须使用处理状态 由于处理订单状态的自定义挂钩 我无法创建自定义状态 理想情况下 手动订单页面中可以勾选一个复选框 勾选后 它将禁止在每种状态下向客户发送电子

随机推荐

  • 为什么x86分页没有特权环的概念?

    早在 1982 年 当 Intel 发布 80286 时 他们在分段方案中添加了 4 个特权级别 环 0 3 由全局描述符表 GDT 和局部描述符表 LDT 中的 2 位指定 在 80386 处理器中 Intel 添加了分页功能 但令人惊讶
  • 如何在另一个 Gui 中启动 JADE Gui?

    如何在另一个 Gui 中启动 JADE Gui 假设我的 Gui 上有一个按钮 点击该按钮后 JADE Gui 将启动 这可能吗 如果是 怎么办 提前致谢 Regards 我假设 JADE Gui 你指的是 JADERMA http jad
  • 窗口位置替换 - 超时帮助? JavaScript问题

    我曾尝试找到一种方法 在我的代码中添加超时 然后再重定向您 我用谷歌搜索并找到了一些帮助 但他们都没有达到我的预期 这会提示用户出生年份并计算年龄 大致 如果用户未满18岁 则带他们去迪士尼乐园 否则允许进入 函数年龄按钮 var AskD
  • 使用 javascript 检测 CSP 违规

    是否可以使用 JavaScript 检测内容安全策略违规 我的 CSP 工作并发送其报告 我看到一些 url 被注入 可能是通过浏览器插件注入的 我想向用户显示一个提示 即某些插件尝试修改页面 我能否以某种方式检测与 javascript
  • 在 swiftUI 中捕获 onLongPressGesture 的 touchDown 位置?

    我正在尝试实现一个自定义上下文菜单 该菜单将在用户触摸的位置长按后出现 我一直无法找到一种方法来捕获 onLongPressGesture 的触地事件的 XY 位置 这就是我开始的地方 struct ExampleView View Sta
  • 从字符串中提取所有链接

    我有一个 javascript 变量 其中包含页面的 HTML 源代码 不是当前页面的源代码 我需要从该变量中提取所有链接 关于什么是最好的方法的任何线索 是否可以为变量中的 HTML 创建一个 DOM 然后遍历它 我不知道这是否是推荐的方
  • 使用 Android 将文本文件上传到 Google Drive

    编辑 我已将文本设置为字符串 如下所示 字符串文本 你好 我想将其转换为纯文本文件 然后上传到 Google 云端硬盘文件夹 我已经尝试过下面的代码 但它不完整 所以我无法说出出现了什么错误 我正在使用 Google Drive 快速启动
  • 在R包/.Rd文件中搜索unicode字符

    如何在 R 包或特定文件中搜索特定的 unicode 字符 我使用的是 RStudio IDE 我正在尝试向 CRAN 提交包裹 所有检查均通过 但以下情况除外 W checking PDF version of manual 49 5s
  • 有没有办法在每个 HTTP 请求的 JSON 响应中重置 $id ? JsonSerializerSettings = PreserveReferencesHandling.Objects

    XYZController cs HttpPost public async Task
  • Clojure:生成所有键盘可输入字符

    Context 我想生成可以通过以下方式生成的所有字符 打开记事本 按键盘上的单个键 按住 Shift 按键盘上的单个键 我目前拥有的 concat range int a int z range int A int Z range int
  • “在 Chrome 网上应用店中注册”未显示在 Google 脚本编辑器中

    我正在尝试将脚本 在脚本库中称为 Paypal 商店 作为 Chrome 网上应用店中的网络应用程序发布 但 Google 脚本的 发布 菜单中未显示 在 Chrome 网上应用店中注册 项目编辑器 此菜单中唯一的项目是 发布到库 和 部署
  • Microsoft ASP.NET Web Pages 2 Data Nuget 包的用途是什么?

    据我了解 ASP NET MVC 4 项目所需的最低 Nuget 包是 微软 ASP NET MVC 4 微软 ASP NET 剃刀 2 微软 ASP NET 网页 2 微软网络基础设施 不过我很想知道 以下包会添加到项目中什么 Micro
  • Ant:如何编写可选的嵌套元素

    说我需要做类似的事情
  • NSDateComponents - EXC_BAD_ACCESS 错误

    我确信有一个简单的答案的基本问题 我正在尝试获取照片的时间戳 当我尝试访问 NSDateComponents 以检索特定日期元素 例如 日 时 我收到 EXC BAD ACCESS 错误 首先 我的代码的相关部分 formattedDate
  • 计算MKPolyline路径的距离?

    我想获取 MKPolyline 路径的米数 以便我可以告诉用户完成路径还剩多少米 我一直在寻找一些东西来做这件事 但我什么也没得到 Thanks 尽管听起来很乏味 但除非您想自己进行数学计算 否则您可能必须迭代该行的思想points 将每个
  • 如何在 Eclipse 中添加视角

    如果我安装了两个版本的 Eclipse 如何将在一个 Eclipse 版本 中安装的透视图添加到另一个版本 首先如何添加视角 即 它们来自哪里 不要告诉我 打开视角 对话框 由于所选答案在 观点从何而来 的细节上有点 差 因此以下是一些精度
  • 已加载 nib 文件但未设置视图出口

    我不小心删除了universityPicker xib 然后用相同的名称创建了一个新的 但无法连接 文件崩溃并给出此消息 reason UIViewController loadViewFromNibNamed bundle loaded
  • 运行时动态转换

    有没有一种方法可以在运行时动态转换 如以下伪代码 foreach DataRow row in table Rows foreach DataColumn col in table Columns if row col DBNull Val
  • 过滤(搜索和替换)InputStream 中的字节数组

    我有一个 InputStream 它将 html 文件作为输入参数 我必须从输入流中获取字节 我有一个字符串 XYZ 我想将此字符串转换为字节格式 并检查从 InputStream 获得的字节序列中是否存在与该字符串匹配的字符串 如果有的话
  • Facebook 爬虫严重攻击我的服务器并忽略指令。多次访问相同资源

    Facebook 爬虫每秒多次访问我的服务器 它似乎忽略了 Expires 标头和 og ttl 属性 在某些情况下 它会在 1 5 分钟内多次访问同一 og image 资源 在一个示例中 爬虫程序在 3 分钟内使用 12 个不同的 IP