Perl:有些网站会阻止 non-browser 请求。但是怎么办?
Perl: Some websites block non-browser requests. But how?
我正在编写一个简单的 Perl 脚本,用于从不同站点获取一些页面。很non-intrusive。我不占用服务器带宽。它检索单个页面而不加载任何额外的 javascript、图像或样式表。
我使用 LWP::UserAgent 检索页面。这在大多数网站上工作正常,但有些网站 return 出现“403 - 错误请求”错误。相同的页面在我的浏览器中加载得很好。我已经检查了来自我的网络浏览器的请求 header 并在尝试在 Perl 中检索相同页面时准确复制了该请求,并且每次我都收到 403 错误。这是一个代码片段:
use strict;
use LWP::UserAgent;
use HTTP::Cookies;
my $URL = "https://www.betsson.com/en/casino/jackpots";
my $browserObj = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 }
);
# $browserObj->cookie_jar( {} );
my $cookie_jar = HTTP::Cookies->new();
$browserObj->cookie_jar( $cookie_jar );
$browserObj->agent( "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0");
$browserObj->timeout(600);
push @{ $browserObj->requests_redirectable }, 'POST';
my @header = ( 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding' => 'gzip, deflate, br',
'Accept-Language' => 'en-US,en;q=0.5',
'Connection' => 'keep-alive',
'DNT' => '1',
'Host' => 'www.bettson.com',
'Upgrade-Insecure-Requests' => '1'
);
my $response = $browserObj->get( $URL, @header );
if( $response->is_success ) {
print "Success!\n";
} else {
print "Unsuccessfull...\n";
}
这些服务器如何区分真实浏览器和我的脚本?起初我以为他们有一些 JavaScript 诡计,但后来我意识到为了让它起作用,页面必须首先由浏览器加载。但是我立即得到这个 403 错误。
我该如何调试?
虽然 403 是机器人检测的典型答案,但在这种情况下,机器人检测不是问题的原因。相反,您的代码中的拼写错误是:
my $URL = "https://www.betsson.com/en/casino/jackpots";
...
'Host' => 'www.bettson.com',
在URL中域名是www.betsson.com
,这应该反映在Host
header中。但是您的 Host
header 略有不同:www.bettson.com
。由于主机 header 的名称错误,请求被拒绝并返回 403 forbidden。
实际上,甚至不需要经历所有这些麻烦,因为看起来根本没有进行机器人检测。 IE。无需使用 header 设置 user-agent 和 fiddle 而是简单的:
my $browserObj = LWP::UserAgent->new();
my $response = $browserObj->get($URL);
我正在编写一个简单的 Perl 脚本,用于从不同站点获取一些页面。很non-intrusive。我不占用服务器带宽。它检索单个页面而不加载任何额外的 javascript、图像或样式表。
我使用 LWP::UserAgent 检索页面。这在大多数网站上工作正常,但有些网站 return 出现“403 - 错误请求”错误。相同的页面在我的浏览器中加载得很好。我已经检查了来自我的网络浏览器的请求 header 并在尝试在 Perl 中检索相同页面时准确复制了该请求,并且每次我都收到 403 错误。这是一个代码片段:
use strict;
use LWP::UserAgent;
use HTTP::Cookies;
my $URL = "https://www.betsson.com/en/casino/jackpots";
my $browserObj = LWP::UserAgent->new(
ssl_opts => { verify_hostname => 0 }
);
# $browserObj->cookie_jar( {} );
my $cookie_jar = HTTP::Cookies->new();
$browserObj->cookie_jar( $cookie_jar );
$browserObj->agent( "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0");
$browserObj->timeout(600);
push @{ $browserObj->requests_redirectable }, 'POST';
my @header = ( 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding' => 'gzip, deflate, br',
'Accept-Language' => 'en-US,en;q=0.5',
'Connection' => 'keep-alive',
'DNT' => '1',
'Host' => 'www.bettson.com',
'Upgrade-Insecure-Requests' => '1'
);
my $response = $browserObj->get( $URL, @header );
if( $response->is_success ) {
print "Success!\n";
} else {
print "Unsuccessfull...\n";
}
这些服务器如何区分真实浏览器和我的脚本?起初我以为他们有一些 JavaScript 诡计,但后来我意识到为了让它起作用,页面必须首先由浏览器加载。但是我立即得到这个 403 错误。
我该如何调试?
虽然 403 是机器人检测的典型答案,但在这种情况下,机器人检测不是问题的原因。相反,您的代码中的拼写错误是:
my $URL = "https://www.betsson.com/en/casino/jackpots";
...
'Host' => 'www.bettson.com',
在URL中域名是www.betsson.com
,这应该反映在Host
header中。但是您的 Host
header 略有不同:www.bettson.com
。由于主机 header 的名称错误,请求被拒绝并返回 403 forbidden。
实际上,甚至不需要经历所有这些麻烦,因为看起来根本没有进行机器人检测。 IE。无需使用 header 设置 user-agent 和 fiddle 而是简单的:
my $browserObj = LWP::UserAgent->new();
my $response = $browserObj->get($URL);