我正在玩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”。
所以我解决了我的问题:) 谢谢你们!
答案 0 :(得分:4)
似乎Win32 :: IE :: Mechanize版本0.009中存在错误。有一个developer release 0.009_17可能会更好。我没有测试过,但至少'sssself'是固定的。如果IE不是必需的,如果不需要浏览器,还有WWW::Mechanize::Firefox
和WWW::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";
};
}