我正试着刮一个网站,不管我尝试什么,我都会收到403个禁止错误:
我尝试了以上所有的代理和不带代理,更改了用户代理,并添加了引用头。
我甚至从Chrome浏览器复制了请求头,并尝试使用PHP发送请求,但仍然收到403个禁止错误。
关于是什么触发网站阻止请求和如何绕过的任何投入或建议?
PHP CURL示例:
$url ='https://www.vitacost.com/productResults.aspx?allCategories=true&N=1318723&isrc=vitacostbrands%3aquadblock%3asupplements&scrolling=true&No=40&_=1510475982858';
$headers = array(
'accept:application/json, text/javascript, */*; q=0.01',
'accept-encoding:gzip, deflate, br',
'accept-language:en-US,en;q=0.9',
'referer:https://www.vitacost.com/productResults.aspx?allCategories=true&N=1318723&isrc=vitacostbrands:quadblock:supplements',
'user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.89 Safari/537.36',
'x-requested-with:XMLHttpRequest',
);
$res = curl_get($url,$headers);
print $res;
exit;
function curl_get($url,$headers=array(),$useragent=''){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_ENCODING, '');
if($useragent)curl_setopt($curl, CURLOPT_USERAGENT,$useragent);
if($headers)curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($curl);
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$response = substr($response, $header_size);
curl_close($curl);
return $response;
}以下是我一直得到的回应:
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
You don't have permission to access
"http://www.vitacost.com/productResults.aspx?"
on this server.<P>
Reference #18.55f50717.1510477424.2a24bbad
</BODY>
</HTML>发布于 2017-11-12 09:53:37
首先,请注意,该网站不喜欢网络抓取。正如@KeepCalmAndCarryOn在一条评论中指出的那样,这个站点有一个/robots.txt,它明确要求机器人不要抓取站点的特定部分,包括您想要抓取的部分。一个好公民虽然没有法律约束力,但会遵守这一要求。
此外,该网站似乎采取了明确的保护,以防止刮刮,并试图确保这是一个真正的浏览器。看起来这个网站就在Akamai CDN的后面,所以也许防刮保护是来自这个CDN。
但是我已经接受了Firefox发送的请求(成功了),然后尝试尽可能地简化它。以下内容目前适用于我,但如果站点更新其浏览器检测,当然可能会失败:
use strict;
use warnings;
use IO::Socket::SSL;
(my $rq = <<'RQ') =~s{\r?\n}{\r\n}g;
GET /productResults.aspx?allCategories=true&N=1318723&isrc=vitacostbrands%3aquadblock%3asupplements&scrolling=true&No=40&_=151047598285 HTTP/1.1
Host: www.vitacost.com
Accept: */*
Accept-Language: en-US
Connection: keep-alive
RQ
my $cl = IO::Socket::SSL->new('www.vitacost.com:443') or die;
print $cl $rq;
my $hdr = '';
while (<$cl>) {
$hdr .= $_;
last if $_ eq "\r\n";
}
warn "[header done]\n";
my $len = $hdr =~m{^Content-length:\s*(\d+)}mi && $1 or die "no length";
read($cl,my $buf,$len);
print $buf;有趣的是,如果我删除Accept头,我得到一个403禁止。如果我移除Accept-Language,它只会挂起。而且有趣的是,它似乎不需要一个用户代理头。
编辑:它看起来像机器人检测也使用发件人的源IP作为特征。虽然上面的代码来自两个不同的系统,但它不能工作在第三个系统(托管在Digitalocean上),而只是挂起。
https://stackoverflow.com/questions/47247122
复制相似问题