8

这是我在 SO 上的第一篇文章,所以要温柔。我什至不确定这是否属于这里,但这里是。

我想访问我的一个个人帐户的一些信息。该网站写得不好,需要我手动输入我想要的信息的日期。这真是一种痛苦。我一直在寻找学习更多 Perl 的借口,所以我认为这将是一个很好的机会。我的计划是编写一个 Perl 脚本来登录我的帐户并为我查询信息。但是,我很快就陷入了困境。

my $ua = LWP::UserAgent->new;
my $url = url 'https://account.web.site';
my $res = $ua->request(GET $url);

生成的网页基本上说我的网络浏览器不受支持。我尝试了许多不同的值

$ua->agent("");

但似乎没什么用。Google-ing around 建议了这种方法,但它也说 perl 是出于恶意原因在网站上使用的。网站会阻止这种方法吗?我想要做的甚至可能吗?有没有更合适的语言?我正在尝试做的事情是合法的还是一个好主意?也许我应该放弃我的努力。

请注意,为防止泄露任何私人信息,我在这里编写的代码并不是我使用的确切代码。不过,我希望这很明显。

编辑:在 FireFox 中,我禁用了 JavaScript 和 CSS。我登录得很好,没有“不兼容的浏览器”错误。这似乎不是 JavaScript 问题。

4

8 回答 8

7

通过抓取获取不同的网页

我们必须做出一个假设,如果给定相同的输入,Web 服务器将返回相同的输出。有了这个假设,我们不可避免地得出结论,我们没有给它相同的输入。在这种情况下,有两种浏览器或 http 客户端:一种为您提供所需的结果(例如,Firefox、IE、Chrome 或 Safari),另一种为您提供所需的结果(例如.、LWP、wget 或 cURL)。

首先消除简单的可能性

在此之前,首先确保简单的 UserAgent 相同,您可以通过浏览whatsmyuseragent.com并将另一个浏览器标题中的 UserAgent 字符串设置为该网站返回的任何内容来执行此操作。您还可以使用 Firefox 的Web 开发人员工具栏来禁用 CSS、JavaScript、Java 和元重定向:这将帮助您通过消除非常简单的东西来跟踪问题。

现在尝试复制工作浏览器

现在有了 Firefox,您可以使用FireBug来分析REQUEST发送的内容。您可以NET在 FireBug 的选项卡下执行此操作,不同的浏览器应该具有可以执行 FireBug 对 FireFox 所做的工具;但是,如果您不了解相关工具,您仍然可以使用tsharkwireshark,如下所述。重要的是要注意tsharkwireshark总是更准确,因为它们在较低级别上工作,至少以我的经验来看,出错的空间较小。例如,您会看到浏览器正在执行的元重定向等内容,有时 FireBug 可能会忘记这些内容。

在您了解第一个有效的网络请求后,请尽力将第二个网络请求设置为第一个。我的意思是正确设置请求标头和其他请求元素。如果这仍然不起作用,您必须知道第二个浏览器在做什么才能查看问题所在。

故障排除

为了解决这个问题,我们必须全面了解来自两个浏览器的请求。第二种浏览器通常比较狡猾,它们通常是库和非交互式命令行浏览器,它们缺乏检查请求的能力。如果他们有能力转储请求,您仍然可以选择简单地检查它们。为此,我建议使用wireshark 和 tshark 套件。立即,您应该被警告,因为这些在浏览器下运行。默认情况下,您将看到实际的网络 (IP) 数据包和数据链路帧。您可以使用这样的命令过滤掉您特别需要的内容。

sudo tshark -i <interface> -f tcp -R "http.request" -V |
perl -ne'print if /^Hypertext/../^Frame/'

这将捕获所有 TCP 数据包,仅显示过滤器http.requests,然后 perl 过滤器仅用于第 4 层 HTTP 内容。您可能还想添加到显示过滤器以仅获取单个 Web 服务器-R "http.request and http.host == ''"

您将要检查所有内容以查看这两个请求是否一致、cookie、GET url、用户代理等。确保该站点没有做一些愚蠢的事情。

2010 年 1 月 23 日更新:根据新信息,我建议设置Accept, and Accept-Language, Accept-Charsetand Accept-Encoding。你可以通过 through 做到这一点$ua->default_headers()。如果您需要从用户代理中获得更多功能,您总是可以将其子类化。我为我的 GData API 采用了这种方法,您可以在 github 上的 UserAgent 子类中找到我的示例

于 2010-01-23T21:18:21.607 回答
4

您可能应该查看WWW::Mechanize,它是LWP::UserAgent的子类,面向那种网站自动化。特别是,请参阅agent_alias 方法

一些网站确实基于 User-Agent 阻止连接,但您可以使用 Perl 将其设置为您想要的任何内容。网站可能还会查找通常由特定浏览器生成的其他请求标头(例如 Accept 标头)并拒绝不包含它们的连接,但是如果您弄清楚它在寻找什么,您也可以添加这些标头.

一般来说,网站不可能阻止其他客户端冒充受支持的浏览器。无论它在寻找什么,您最终都可以复制它。

它也可能正在寻找 JavaScript 支持。在这种情况下,您可能会查看WWW::Scripter,它是 WWW::Mechanize 的子类,添加了 JavaScript 支持。这是相当新的,我还没有尝试过。

于 2010-01-23T20:55:47.160 回答
2

该线程几乎可以肯定不仅仅是更改用户代理。

我看到两条路。我们可以尝试在浏览器中关闭 javascript 和 css,并了解更多关于在依赖 LWP::UserAgent 时进入 HTTP::Request 和 HTTP::Response 对象,或者转到 WWW::Scripter 并使用 javascript。

就在粗略的 Craigslist 文字广告中,有三页密密麻麻、几乎没有空间的 javascript 和 css,然后它们加载更多和专门的代码,这样如果我通过 comcast 进来,我就会找到特殊的 javascript,只针对 comcast 用户,已加载到最后一页。他们这样做的方式是试图通过将代码放在 HEAD 中来破坏机器人,这些代码解释了 HTML 1.0 和 1.1 之间的差异,说,哦,有些地方出了点问题,你需要刷新 http,然后对你施加压力有额外的代码来窥探 isp 和谁知道是什么,肯定是 cookie 信息(当你学习如何减慢 LWP 并插入回调代码以像 *shark 但在 perl 中窥探时,你可以随时打印出 cookie,还可以查看服务器如何不断尝试更改“你的”标题和“你的”请求——重新协商“

CL 将一个随机 ID 号放入 Alice 的 HEAD,然后低声说你需要一个 http 请求才能吞下红色药丸,别再把它藏在你的舌头下。这样,大多数机器人会阻塞并接受一个虚假的净化页面,即截断的“主页”。此外,如果我从页面上抓取 url,我无法使用 LWP “点击”它们,因为我从未学习过我的 ID,也没有在 $ua->get($ url&ID=9dd887f8f89d9" ); 或者简单的 get 可以与 &ID 一起使用。它不仅仅是用户代理,但你可以做到,并且你会得到你需要的所有帮助

如您所见,第一个路径是关闭所有这些,看看您是否可以了解重新协商请求的 URI,不是原始 URL,而是 URI。然后得到它,没有 javascript,没有 WWW::Scripter。听起来 LWP 会为你工作。我想听听更多关于最初更改 default_header 中的 ACCEPT 的信息,以及服务器是否说,哦,你的意思是 ACCEPT 这个和这个和这个,在重新协商请求对象中吞下红色药丸。您可以通过在请求和响应对话中插入回调来窥探它。

第二条路,WWW::Scripter,只有当我们决定吞下红色药丸,然后进入爱丽丝的兔子洞,也就是矩阵时。perl 哲学要求在努力工作之前用尽其他可能性。否则我们就不会学习我们的 101 http prereqs,所以升级到更大的锤子就是这样,或者为阿司匹林滴酸,还是不?

于 2012-01-16T20:46:05.107 回答
0

我尝试了许多不同的值

$ua->代理(“”);

但似乎没什么用。

好吧,你想告诉我们你尝试过的那些东西是什么吗?

我通常做的是打字

javascript:prompt('your agent string is',navigator.userAgent)

进入我的常规浏览器的 URL 栏,按 Enter,然后剪切并粘贴它告诉我的内容。使用wireshark和监控实际数据包肯定是矫枉过正吗?您尝试访问的网站无法知道您正在使用 Perl。只要告诉它它希望听到的任何东西。

于 2010-01-24T08:26:00.087 回答
0

工具:带有 TamperData 和 LiveHTTPHeaders 的 Firefox、Devel::REPL、LWP。

分析:在浏览器中,关闭Javascript和Java,从目标网站删除所有cookies,启动TamperData记录,登录网站。停止 TamperData 记录并回顾您在登录过程中可能放置的许多请求。找到第一个请求(您故意提出的请求)并查看其详细信息。

实验:开始re.pl,并开始重新创建浏览器的交互。

use LWP::UserAgent;

my $ua = LWP::UserAgent->new(
  agent      => $the_UA_of_the_browser,
  cookie_jar => HTTP::Cookies->new(hide_cookie2 => 1),
);
$ua->default_headers(HTTP::Headers->new(
  %the_headers_sent_by_the_browser,
));

my $r = $ua->get($the_URL);
$r->content($r->decoded_content); print $r->as_string;

所以这是第一步。如果您在任何时候收到不匹配的响应,则说明您做错了。您通常可以[1] 通过查看$r->request并与 Firefox 发送的请求进行比较来了解内容。重要的是要记住没有魔法,你知道服务器知道的一切。如果您无法对看似相同的请求获得相同的响应,那么您错过了一些东西。

到达第一页通常是不够的。您可能需要解析表单(使用HTML::Form),遵循重定向(如上所述,UA 会自动执行此操作,但有时需要将其关闭并手动执行),并尝试对一个奇怪的黑客进行逆向工程最简单的提示中的登录顺序。祝你好运。

[1]:除了 LWP 的 cookie 实现中的某些错误,我不会在这里详细说明。即使这样,如果您知道自己在寻找什么,您也可以发现它。

于 2010-02-03T17:50:03.047 回答
0

您的 perl 脚本是否与您引用的 firefox 浏览器在同一台机器上运行?它可以基于子网或传入 IP 地址进行过滤。您的网址是 https,因此您的浏览器上可能还加载了一些 PSK(预共享密钥)或证书,以符合服务器的预期。在内部公司内部网站之外极不可能。

于 2011-08-01T23:17:15.200 回答
0

我刚刚注意到一些事情。这一行:

my $res = $ua->request(GET $url);

它在我的机器上根本不起作用。但我通过将其更改为:

my $res = $ua->get($url);
于 2013-09-28T19:01:45.480 回答
0

添加推荐人部分使其对我有用:

$req = HTTP::Request->new(GET => $url);
$req->header(Accept => "text/html, */*;q=0.1", referer => 'http://google.com');
$res = $ua->request($req);
print $res->status_line;
于 2014-04-06T07:42:30.787 回答