繁体   English   中英

我如何使用和调试WWW :: Mechanize?

[英]How do I use and debug WWW::Mechanize?

我是Perl的新手,当我尝试自动化一些项目工作时,我正在学习。 到目前为止它已经很有趣了。

我正在为客户生成报告。 我可以从我可以访问的网页上获取此报告。 首先,我需要用我的用户名,密码填写表格,然后从下拉列表中选择一个服务器,然后登录。其次,我需要点击报告部分的链接。 第三,需要填写表格来创建报告。

这是我到目前为止写的:

my $mech = WWW::Mechanize->new();
my $url = 'http://X.X.X.X/Console/login/login.aspx';

$mech->get( $url );

$mech->submit_form(
     form_number => 1,
     fields      =>{
        'ctl00$ctl00$cphVeriCentre$cphLogin$txtUser'  => 'someone',
        'ctl00$ctl00$cphVeriCentre$cphLogin$txtPW'    => '12345',
        'ctl00$ctl00$cphVeriCentre$cphLogin$ddlServers'  => 'Live',
     button => 'Sign-In'
   },   
);
die unless ($mech->success);

$mech->dump_forms();

我不明白为什么,但是,在此之后我看看什么转储输出,我看到第一个登录页面的代码,而我相信我应该在我成功登录后到达下一页。

可能有一些cookie可以影响我和登录尝试吗?

还有别的我做错了吗?

Yaniv,感谢您的帮助

这是事后几个月,但我根据我提出的类似问题解决了同样的问题。 请参阅是否可以从客户端自动回发? 了解更多信息。

我使用Python的Mechanize而不是Perl,但同样的原则适用。

总结我之前的回应:

ASP.NET页面在表单中需要一个名为__EVENTTARGET的隐藏参数,当您正常使用mechanize时,该参数将不存在。

当普通用户访问时,这些页面上有一个__doPostBack('foo')函数,通过每个链接上的javascript onclick事件为__EVENTTARGET提供相关值,但由于机械化不使用javascript,您需要自己设定这些值。

python解决方案如下所示,但它不应该太难以适应perl。

def add_event_target(form, target):
    #Creates a new __EVENTTARGET control and adds the value specified
    #.NET doesn't generate this in mechanize for some reason -- suspect maybe is 
    #normally generated by javascript or some useragent thing?
    form.new_control('hidden','__EVENTTARGET',attrs = dict(name='__EVENTTARGET'))
    form.set_all_readonly(False)
    form["__EVENTTARGET"] = target

如果您使用的是Windows,请在手动执行此过程时使用Fiddler查看正在发送的数据,然后使用Fiddler将其与脚本执行时捕获的数据进行比较。

根据我的经验,在检查表单帖子时,像Fiddler这样的Web调试代理比Firebug更有用。

你只能机械化你知道的东西。 在您编写更多代码之前,我建议您使用Firebug之类的工具,并在手动执行此操作时检查浏览器中发生的情况。

当然可能会使用cookie。 或者你忘了一个隐藏的表格参数? 只有你可以告诉。

编辑:

  • WWW :: Mechanize应该在没有任何进一步干预的情况下处理cookie。
  • 您应该始终检查您调用的方法是否成功。 第一个get()是否有效?
  • 查看服务器日志以查看实际请求的内容以及作为响应发送的HTTP状态代码可能很有用。

我发现在使用WWW::Mechanize编写Web自动化时使用Wireshark实用程序非常有用。 它会以几种方式帮助您:

  1. 使您能够意识到您的HTTP请求是否成功。
  2. 查看HTTP级别失败的原因。
  3. 跟踪传递给服务器的确切数据,并查看收到的内容。

只需为网络流量设置HTTP过滤器并启动Perl脚本。

aspx的一个非常简短的要点就是它将所有本地会话信息保存在一般aspxform中以“__”为前缀的几个变量中。 通常这是一个顶级形式,所有表单元素都将成为其中的一部分,但我想这可能因实现而异。

对于我正在处理的特定实现,我需要担心其中的两个状态变量,具体来说:

__VIEWSTATE
__EVENTVALIDATION.

您的目标是确保将这些变量提交到您提交的表单中,因为它们可能是我上面提到的主表单aspxform的一部分,并且您可能提交的表单不同于此。

当浏览器加载一个aspx页面时,一段javascript会在asp服务器/客户端交互中传递此会话信息,但当然我们没有使用perl mechanize的那种奢侈,所以你需要通过添加手动发布这些使用mechanize的当前表单元素。

在我刚刚解决的情况下,我基本上做了这个:

my $browser = WWW::Mechanize->new( );

# fetch the login page to get the initial session variables
my $login_page = 'http://www.example.com/login.aspx';
$response = $browser->get( $login_page);

# very short way to find the fields so you can add them to your post
$viewstate = ($browser->find_all_inputs( type => 'hidden', name => '__VIEWSTATE' ))[0]->value;
$validation = ($browser->find_all_inputs( type => 'hidden', name => '__EVENTVALIDATION' ))[0]->value;

# post back the formdata you need along with the session variables
$browser->post( $login_page, [ username => 'user', password => 'password, __VIEWSTATE => $viewstate, __EVENTVALIDATION => $validation ]);

# finally get back the content and make sure it looks right
print $response->content();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM