Way*_*tty 12 php facebook web-crawler facebook-graph-api
Facebook Crawler每秒都会多次点击我的服务器,它似乎忽略了Expires头和og:ttl属性.
在某些情况下,它在1-5分钟的空间内多次访问相同的og:图像资源.在一个示例中 - 爬虫使用12个不同的IP地址在3分钟的过程中访问相同的图像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
Run Code Online (Sandbox Code Playgroud)
根据Facebook的文档,og:图像是什么:
有人将内容分享到Facebook时显示的图像的URL.有关详细信息,请参阅下文,并查看我们的最佳做法指南,了解如何指定高质量的预览图像.
我在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
Run Code Online (Sandbox Code Playgroud)
根据Facebook的Object Properties文档,og:ttl属性是:
秒,直到该页面应该被重新删除.使用此权限来限制Facebook内容抓取工具.允许的最小值为345600秒(4天); 如果设置较低的值,将使用最小值.如果您不包含此标记,则ttl将根据您的Web服务器返回的"Expires"标头计算,否则默认为7天.
我已将此og:ttl属性设置为2419200,这是将来28天.
我一直试图用这样的东西:
header("HTTP/1.1 304 Not Modified");
exit;
Run Code Online (Sandbox Code Playgroud)
但我担心Facebook的Crawler会忽略标题并将图像标记为已损坏 - 从而从共享故事中删除图像预览.
有没有办法防止爬虫这么快就回来打这些资源?
显示我的开放图和元属性的示例代码:
<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" />
Run Code Online (Sandbox Code Playgroud)
Smu*_*uuf 11
之后,我几乎尝试了一切与高速缓存,头部并没有什么,从"过分热情"脸谱抓取保存在我们的服务器的唯一的事情(用户代理facebookexternalhit)被简单地拒绝访问,并发送回HTTP/1.1 429 Too Many RequestsHTTP响应,当爬虫"抓取太多".
不可否认,我们有数千张我们希望抓取工具抓取的图片,但Facebook抓取工具实际上每小时都会向我们的服务器发送数万个请求(是的,反复使用相同的网址).我记得在一个点上使用te 用户代理从不同Facebook的IP地址每小时发出40 000个请求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);
}
Run Code Online (Sandbox Code Playgroud)
您还需要配置重写以将针对您的图像的所有请求传递到此PHP脚本:
.../images/.htaccess (如果您使用的是Apache)
RewriteEngine On
RewriteRule .* index.php [L]
Run Code Online (Sandbox Code Playgroud)
看起来爬虫"理解这种"方法并有效地将尝试率从每小时数万个请求减少到每小时数百个/数千个请求.
我收到了 Facebook 团队自己的回复。希望它为爬虫如何处理图像 URL 带来一些澄清。
它是这样的:
Crawler 处理图像 URL 的方式与其他 URL 不同。
我们多次抓取图像,因为我们有不同的物理区域,每个区域都需要获取图像。由于我们有大约 20 个不同的区域,开发人员应该预计每个图像有大约 20 个调用。一旦我们提出这些请求,它们就会在我们的缓存中停留大约一个月 - 我们需要经常重新抓取这些图像以防止平台上的滥用(恶意行为者可以让我们抓取一个良性图像,然后将其替换为令人反感的图像) .
所以基本上,您应该期望 og:image 中指定的图像在共享后会被点击 20 次。然后,一个月后,它会再次被刮掉。
| 归档时间: |
|
| 查看次数: |
2562 次 |
| 最近记录: |