如何摆脱“无法找到对象方法”警告“通过包”sssself“错误在IE :: Mechanize?

时间:2010-02-27 01:52:32

标签: perl hashref

我正在玩Win32 :: IE :: Mechanize。我正在尝试使用脚本自动访问我的六个基于Web的电子邮件帐户。该脚本基本上工作,但perl抛出一种神秘的“无法定位对象方法”警告“通过包”sssself“(也许你忘了加载”sssself)“错误。尽管有错误,脚本仍然可以完成工作但是我想摆脱它并理解它为什么会发生。以下是脚本。请提交我可以改进代码的地方。谢谢你。

use strict;
use Win32::IE::Mechanize;


my @accounts = (
'http://mail.21cn.com',
'frmmail1',
    {
        'Username' => 'myusername',
        'passwd' => 'mypassword',
        },
'http://mail.126.com',
'form',
    {
        'user' => 'myusername',
        'password' => 'mypassword',
        },
......
......
......
    );

sub arg{
shift (@accounts);
}

while(@accounts){
my $mech = Win32::IE::Mechanize->new(visible=>1);
my $url = arg;
my $form = arg;
my $account = arg;

$mech->get($url);
$mech->form_name($form);
eval {$mech->set_fields(%$account);}; 
warn $@ if $@;
$mech->click();
}

我知道这行

有问题
$mech->set_fields(%$account);

但我该如何纠正呢?或者我应该删除

warn $@ if $@;

并假装没有错?

欢迎任何评论:)

更新

非常感谢@daotoad清理我丑陋的代码:)我认为嵌套结构更易于维护并且更好看。

并感谢@Eric,感谢您指出我所讨论的模块的更好版本:)

嗯,问题是当Win32 :: IE:Mechanize 0.009给出以下神秘错误消息

  

找不到对象方法“警告”通过   包“sssself”(也许你忘了   to l oad“sssself”?)at   C:/Perl/site/lib/Win32/IE/Mechanize.pm   第971行。

0.009_17 Dev Release给了我一些非常有意义的信息:

  

没有名称'Username'的inputcontrol   在E:\ mailme.pl第33行

记住这个错误信息时,我检查了登录页面的源文件,结果发现字段ID应该是“UserName”,而不是“Username”。

所以我解决了我的问题:) 谢谢你们!

2 个答案:

答案 0 :(得分:4)

似乎Win32 :: IE :: Mechanize版本0.009中存在错误。有一个developer release 0.009_17可能会更好。我没有测试过,但至少'sssself'是固定的。如果IE不是必需的,如果不需要浏览器,还有WWW::Mechanize::FirefoxWWW::Mechanize

答案 1 :(得分:2)

我没有时间给你很好的答案ATM,但这里是一个清理代码。看看评论。如果您对我做了什么或为什么有任何疑问,请在下面发表评论,我会更新问题。

#!/usr/bin/perl
use strict;
use warnings;  # Use warnings - see perldoc perllexwarn

use Try::Tiny;  # Don't try to handle your own exceptions.  Try::Tiny does it better.

use Win32::IE::Mechanize;

# Use a nested structure so you don't have to keep popping stuff off a global array.   
my @accounts = (

    {   url       => 'http://mail.21cn.com',
        form_id => 'frmmail1',
        fields => {
            Username   => 'myusername',
            passwd     => 'mypassword',
        }
    },
    {   url => 'http://mail.126.com',
        form_id => 'form',
        fields => {
            user => 'myusername',
            password => 'mypassword',
        },
    },
);

# No messing about with @accounts means we can use a for loop.
for my $account (@accounts) {

    # Its not necessary to unpack these into scalars.
    # It makes sense if you are going to transform the values or use them many times.
    my $url    = $account->{url};
    my $form   = $account->{form_id};
    my $fields = $account->{fields};

    my $mech = Win32::IE::Mechanize->new(visible=>1);

    $mech->get($url);
    $mech->form_name($form);

    # Exception handling redone with Try::Tiny    
    $mech->click() if try { 
        $mech->set_fields(%$fields);
        1;
    }
    catch {
        warn "Form failed - $_\n";
    };
}