perl WWW :: Mechanize似乎无法找到正确的表单或分配字段或点击提交

时间:2016-01-21 22:51:30

标签: forms perl

因此,我尝试创建一个登录到SAP BusinessObjects Central Management Console(CMC)页面的perl脚本,但它看起来甚至看起来没有找到正确的表单或查找正确的字段甚至点击提交。

这是我的代码:

use strict;
use warnings;
use WWW::Mechanize;
use HTTP::Cookies;

my $mech = WWW::Mechanize->new();
$mech->cookie_jar(HTTP::Cookies->new());
$mech->get("http://myserver:8080/BOE/CMC");
$mech->form_name("_id2");
$mech->field("_id2:logon:CMS", "MYSERVER:6400");
$mech->field("_id2:logon:SAP_SYSTEM", "");
$mech->field("_id2:logon:SAP_CLIENT", "");
$mech->field("_id2:logon:USERNAME", "MYUSER");
$mech->field("_id2:logon:PASSWORD", "MYPWD");
$mech->field("_id2:logon:AUTH_TYPE", "secEnterprise");
$mech->click;
print $mech->content();

当我运行它时,我没有收到任何错误,但我得到的输出是登录页面。更令人费解的是,它似乎并不接受我发送的字段值(输出将显示默认值而不是我指定的值)。输入错误的用户或密码并不会改变任何内容 - 没有错误,但我只是使用默认值返回登录页面

我认为脚本本身很好,因为我更改了必要的字段,我能够登录我们的Nagios页面(输出页面肯定显示了Nagios的详细信息)。我认为CMC页面不是那么简单,但我需要帮助确定如何使其工作。

我尝试过的事情:

1

use Data::Dumper;
print $mech->forms;
print Dumper($mech->forms());

给我的是:     目前的形式是:WWW :: Mechanize = HASH(0x243d828)

Dumper输出的一部分是:

'attr' => {
         'target' => 'servletBridgeIframe',
         'style' => 'display:none;',
         'method' => 'post'
       },
'inputs' => []

我只展示了Dumper输出的那一部分,因为它似乎是相关部分。当我在Nagios页面尝试同样的事情时,' attr'该节有一个名字'上面没有的字段。 Nagios页面还有输入'输入'例如' useralias'和密码'但上面没有任何条目。

2

$mech->form_number(1);

由于我不确定我是否正确引用了表单,我只是尝试使用它找到的第一个表单(页面只有一个表单)。我的结果是相同的 - 没有错误,输出是具有默认值的登录页面。

3

我在字段名称中使用下划线(_)和冒号(:)来逃避(使用' \')。

我已经搜索过,并没有找到任何说我必须逃避任何角色的东西,但值得一试。我所知道的是,Nagios页面字段名称只包含字母而且有效。

我从Chrome的开发者工具中获得了字段名称。例如,“用户名”表单字段显示:

<input type="text" id="_id2:logon:USERNAME" name="_id2:logon:USERNAME" value="Administrator">

我不知道Mechanize是否存在以下划线开头的名称或包含冒号的名称的问题。

4

$mech->click("_id2:logon:logonButton");

因为我不确定&#34;登录&#34;按钮被点击我试图指定它,但它给了我一个错误:

No clickable input with name _id2:logon:logonButton at /usr/share/perl5/WWW/Mechanize.pm line 1676

这可能是因为按钮上没有定义名称(我使用的是id),但我认为值得一试。这是按钮的代码:

<input type="submit" id="_id2:logon:logonButton" value="Log On" class="logonButtonNoHover logon_button_no_hover" onmouseover="this.className = 'logonButtonHover logon_button_hover';" onmouseout="this.className = 'logonButtonNoHover logon_button_no_hover';">

表格上只有一个按钮,所以我不需要指定它(我不需要为Nagios页面)

5

Mechanize的交互式shell

这是我尝试检索页面上所有表单时的输出:

$ perl -MWWW::Mechanize::Shell -eshell
(no url)>get http://myserver:8080/BOE/CMC
Retrieving http://myserver:8080/BOE/CMC(200)
http://myserver:8080/BOE/CMC>forms
Form [1]
POST http://myserver:8080/BOE/CMC/1412201223/admin/logon.faces

帮助!

我真的不懂perl所以我不知道如何进一步解决这个问题 - 特别是因为我没有看到错误。如果有人可以指导我尝试其他事情,那将会有所帮助。

3 个答案:

答案 0 :(得分:1)

在这个DOM和Javascript时代,Web自动化有很多可能出错的地方。从您的结果来看,似乎表单可能是在浏览器空间中构建的,这可能很难以编程方式处理。

可以肯定的是转储原始响应并查看它包含的表单代码。

如果事实证明是你的问题,那么你最简单的追索就是Mozilla::Mechanize

答案 1 :(得分:1)

在处理表单时,有时复制表单生成的请求比尝试通过Mechanize处理表单更容易。

尝试使用浏览器的开发人员工具来监控手动登录网站时会发生什么(在Firefox或Chrome中,它将位于“网络”标签下),然后使用Mechanize生成相同的请求。

例如,生成的代码MIGHT类似于:

my $post_data => {
    '_id2:logon:CMS' => "MYSERVER:6400",
    '_id2:logon:SAP_SYSTEM' => "",
    '_id2:logon:SAP_CLIENT' => "",
    '_id2:logon:USERNAME' => "MYUSER",
    '_id2:logon:PASSWORD' => "MYPWD",
    '_id2:logon:AUTH_TYPE' => "secEnterprise",
};

$mech->post($url, $post_data);
unless ($mech->success()){
    warn "Failed to post to $url: " . $mech->response()->status_line() . "\n";
}
print $mech->content();

%post_data应该与手动帖子中传递给网站的数据完全匹配,而不仅仅是HTML中的内容 - 在实际发布之前,可以通过javascript转换键或数据。

答案 2 :(得分:1)

我有一个比我更有知识的人给我帮助。主要障碍是如何在框架中构建页面以及它是如何操作的。以下是详细信息:

这是工作代码:

use strict;
use warnings;
use WWW::Mechanize;
use HTTP::Cookies;

my $mech = WWW::Mechanize->new();
$mech->cookie_jar(HTTP::Cookies->new());
$mech->get("http://myserver:8080/BOE/CMC/0000000000/myuser/logon.faces");
$mech->form_id("_id2");
$mech->field("_id2:logon:CMS", "MYSERVER:6400");
$mech->field("_id2:logon:SAP_SYSTEM", "");
$mech->field("_id2:logon:SAP_CLIENT", "");
$mech->field("_id2:logon:USERNAME", "MyUser");
$mech->field("_id2:logon:PASSWORD", "MyPwd");
$mech->field("_id2:logon:AUTH_TYPE", "secEnterprise");
$mech->click;
$mech->get("http://myserver:8080/BOE/CMC/0000000000/myuser/App/home.faces?service=%2Fmyuser%2FApp%2FappService.jsp&appKind=CMC");
$output_page = $mech->content();
if (index($output_page, "Welcome:") != -1)
{
        print "\n\n+++++ Successful login! ++++++\n\n";
}
else
{
        print "\n\n----- Login failed!-----\n\n";
}

为了验证我已成功登录,我保持简单,只是搜索了#34;欢迎:&#34;文本(如&#34;欢迎:MyUser&#34;)。