【发布时间】:2020-07-26 00:03:15
【问题描述】:
我正在编写一个简单的 Perl 脚本,它可以从不同的站点获取一些页面。这是非常非侵入性的。我不占用服务器带宽。它检索单个页面而不加载任何额外的 javascript、图像或样式表。
我使用 LWP::UserAgent 来检索页面。这在大多数网站上都可以正常工作,但有些网站会返回“403 - 错误请求”错误。相同的页面在我的浏览器中加载得很好。我已经从我的网络浏览器检查了请求标头,并在尝试在 Perl 中检索同一页面时准确地复制了该标头,并且每次我收到 403 错误。这是一个代码sn-p:
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 错误。
我可以做些什么来调试这个?
【问题讨论】:
-
有几种方法可以检测机器人。仅通过您的代码和该代码无法绕过机器人检测的信息,无法说出您的特定但未知站点在做什么。
-
“有几种方法可以检测机器人”。您能说出一个无需服务器查看发送的标头即可工作的名称吗?这不依赖于被服务页面中的 javascript?
-
"...没有服务器查看正在发送的标头..." - 为什么不查看标头?仅仅因为您认为您从浏览器中获取了标头并不意味着 LWP 发送的标头与浏览器完全相同。它将更改顺序(排序),添加 TE 标头,拥有自己的 User-Agent,摆弄 Connection 标头... - 请参阅pastebin.com/MnsaY2hv。因此,您会得到一个浏览器不典型的请求标头。查看标头是机器人检测最简单的事情之一,即如果这些已经不典型,则无需使用更高级的方法。
-
标头完全相同(由流量嗅探器确认)。除了可能的顺序,但这也因浏览器而异。正如您在上面的代码中看到的,用户代理是从我的浏览器中复制的。浏览器和我的脚本发送的标头之间没有明显的区别(除了顺序,但同样,这因浏览器而异)。
-
您是否尝试在
$cookie_jar中使用浏览器中的cookie 文件? cookie 很有可能是使用您的 perl 脚本无法处理的一些 javascript 设置的。
标签: perl lwp-useragent