有一个名为 https://www.guidgenerator.com/online-guid-generator.aspx 的网站,它生成全局唯一标识符。我正在尝试使用 perl 的 Mechanize 发布到网站以提取该指南。我意识到这是基于 javascript 的,但想知道我是否可以发布正确的帖子来提取号码。我从浏览器中跟踪它,并在请求中获得了所有标头,但返回的 html 不包含 guid。
这是成功运行的结果:
<textarea name="txtResults" rows="2" cols="20" id="txtResults" style="font-family:Courier New,Courier,monospace;font-size:Larger;font-weight:bold;高度:152px;宽度:421px;">qk5DF22bhkm4C2AwZ5OcZw==</textarea>
这是我的脚本:
<textarea name="txtResults" rows="2" cols="20" id="txtResults" style="font-family:Courier New,Courier,monospace;font-size:Larger;font-weight:bold;高度:152px;宽度:421px;"></textarea>
这是页面内的表单:
在我的脚本中,我转储了以下所需的表单和输入字段:
my @forms = $mech->forms; foreach my $form (@forms) { my @inputfields = $form->param; print Dumper \@inputfields; }
结果
$VAR1 = [ '__EVENTTARGET', '__EVENTARGUMENT', '__LASTFOCUS', '__VIEWSTATE', '__VIEWSTATEGENERATOR', '__EVENTVALIDATION', 'txtCount', 'chkUppercase', 'chkBrackets', 'chkHypens', 'chkBase64', 'chkRFC7515', 'chkURL', 'LocalTimestampValue', 'btnGenerate', 'txtResults' ];
这就是帖子
my $mainpage = "https://www.guidgenerator.com/online-guid-generator.aspx"; $mech->post( "$mainpage", fields => { 'txtCount' => "1", 'chkBase64' => "on", 'LocalTimestampValue' => "Date%28%29.getTime%28%29", 'btnGenerate' => "Generate+some+GUIDs%21", 'txtResults' => "", '__EVENTTARGET' => 'on', '__EVENTARGUMENT', => 'on', '__LASTFOCUS', => 'on', '__VIEWSTATEGENERATOR' => "247C709F", '__VIEWSTATE' => 'on', '__EVENTVALIDATION' => 'on', 'chkUppercase' => 'off', 'chkBrackets' => 'off', 'chkHypens' => 'off', 'chkRFC7515' => 'off', 'chkURL' => 'off', }, );
当我在网站上进行跟踪时,我得到了标头,但还有另一个名为“有效负载”的选项卡。其中包含上面列出的大部分字段。我尝试将这些字段输入到 POST 中,但不确定我是否应该以不同的方式执行此操作,或者它并不重要,因为它是 javascript?
我知道这是很多信息。我什至不确定 Perl 的机械化可以提取这些信息。任何帮助,将不胜感激。请让我知道您希望我在此处发布的任何其他数据。
P粉7148900532024-04-03 09:56:29
您可以使用 Mech 的内置功能来执行此操作。无需提交任何额外的字段或标头。
use strict;
use warnings;
use feature 'say';
use WWW::Mechanize;
my $mech = WWW::Mechanize->new;
$mech->get('https://www.guidgenerator.com/online-guid-generator.aspx');
$mech->field( txtCount => 10 );
$mech->click;
say $mech->value('txtResults');
这将输出如下内容:
$ perl mech.pl 211b3cad1665483ca303360bdbda0c61 ecc3348d83cb4bb5bdcb11c6148c5ae1 0a3f2fe5748946a1888a4a5bde8ef2e6 acb26deb9fda4411aa64638cdd1ec5f1 2afe609c355b4a10b6a0ae8c74d3aef1 30fd89ab170147cfb24f131346a203e3 2301d258e1d045aa8f0682f2ea14464c f064507ca3e14a4eb860b0a30ba096ed 9a42b15d5c79420c921dcc07c306459b 5bea2e345f75453caaf795681963866a
这里的关键是你不能使用 $mech- >submit
因为这不会提交提交按钮的值。这有点烦人。因此,您必须使用 $mech->click
,它假装单击了默认表单的默认提交按钮,因此也提交了该值。这就是按钮在表单上的工作方式,在本例中,后端检查值以查看单击了哪一个。
然后您可以使用 $mech->value
获取字段值。您可能想要 split
来进一步处理它。
该页面中的 JavaScript 实际上与功能完全无关。它所做的只是保存和恢复您在 cookie 中选择的设置,这样当您回来时,相同的复选框将被选中。这很好,但现在在前端使用本地存储可能会更好。然而,你根本不需要处理 JS 来抓取这个页面。主要功能是后端。
您可能还对 $mech->dump_forms
,这是一个很好的调试辅助工具,可以打印出所有带有字段和值的表单。使用 Mech(或任何基于 LWP 的类)时另一个很好的调试辅助工具是 LWP::ConsoleLogger ::无处不在。这就是我用来将程序的请求与浏览器的请求进行比较以找到丢失的按钮表单字段的方法。
免责声明:我是 WWW::Mechanize 的维护者,我编写了 LWP::ConsoleLogger::Everywhere。