Forms perl WWW::Mechanize可以';似乎找不到正确的表单、分配字段或单击“提交”

Forms perl WWW::Mechanize可以';似乎找不到正确的表单、分配字段或单击“提交”,forms,perl,Forms,Perl,因此,我试图创建一个perl脚本,登录到SAP BusinessObjects中央管理控制台(CMC)页面,但它看起来甚至没有找到正确的表单或字段,甚至没有单击Submit 这是我的密码: use strict; use warnings; use WWW::Mechanize; use HTTP::Cookies; my $mech = WWW::Mechanize->new(); $mech->cookie_jar(HTTP::Cookies->new()); $mech

因此,我试图创建一个perl脚本,登录到SAP BusinessObjects中央管理控制台(CMC)页面,但它看起来甚至没有找到正确的表单或字段,甚至没有单击Submit

这是我的密码:

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. 这给了我的是: 当前表单为:WWW::Mechanize=HASH(0x243d828)

转储程序输出的一部分是:

'attr' => {
         'target' => 'servletBridgeIframe',
         'style' => 'display:none;',
         'method' => 'post'
       },
'inputs' => []
我只展示了转储程序输出的这一部分,因为这似乎是相关的部分。当我在Nagios页面上尝试同样的方法时,“attr”部分有一个上面没有的“name”字段。Nagios页面也有“输入”条目,如“useralias”和“password”,但上面没有任何条目

2. 因为我不确定是否正确引用了表单,所以我让它尝试使用它找到的第一个表单(该页面无论如何只有一个表单)。我的结果是相同的-没有错误,输出是带有默认值的登录页面

3. 我把字段名中的下划线(\)和冒号(:)转义(用“\”)弄得一团糟

我已经搜索过了,没有发现任何东西表明我必须逃离任何角色,但值得一试。我所知道的是,Nagios页面字段名只包含字母,而且有效

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

<input type="text" id="_id2:logon:USERNAME" name="_id2:logon:USERNAME" value="Administrator">
由于我不确定是否单击了“登录”按钮,我尝试指定它,但它给了我一个错误:

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';">
救命啊!
我真的不懂perl,所以我不知道如何进一步解决这个问题——特别是因为我没有看到错误。如果有人能指导我尝试其他东西,那将是很有帮助的。

在这个DOM和Javascript的时代,Web自动化可能会出现很多问题。从您的结果来看,表单可能是在浏览器空间中构建的,这很难通过编程来处理

确保的方法是转储原始响应并查看其包含的表单代码


如果这是你的问题,你最简单的求助方式是

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

尝试使用浏览器的开发工具来监控手动登录站点时发生的情况(在Firefox或Chrome中,它将位于网络选项卡下),然后使用Mechanize生成相同的请求

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

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_数据应该与手动发布到站点中的数据完全匹配,而不仅仅是HTML中的数据——在实际发布之前,键或数据可以通过javascript进行转换。

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

  • 包含登录页的框架的URL为“”。页面的主框架中有一个表单,但它不是登录表单,这解释了为什么我原始代码中的表单没有我期望的登录字段
  • 我遇到的另一个“问题”是,成功登录后,该站点会将您重定向到另一个URL:“”。因此,为了检查登录是否成功,我必须获取这个URL并检查我决定查找的任何文本
  • 我还必须按id而不是名称引用登录表单(因为表单没有名称)
以下是工作代码:

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";
}

为了验证我是否成功登录,我非常简单,只需搜索“欢迎:”文本(如“欢迎:我的用户”)。

1)使用
$mech->dump_forms()
要仔细检查字段的名称2)使用
$mech->submit\u form(带\u fields=>{…})
。类似“它需要javascript支持”的内容可能会变成现实。感谢您的回复。我会调查的。我没能成功地在我们的Ubuntu服务器上安装Mozilla::Mechanize——陷入了“dll地狱”(或者现在叫什么)。我能够通过apt-get安装它的两个prereq中的一个,但是另一个不是那么容易,我很快就进入了cpan兔子洞。尽管如此,我还是很感激你的回复。谢谢你的回复。我先试试Mozilla::Mechanize的建议,看看我能做多少。
<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';">
$ 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
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();
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";
}