tags:

views:

124

answers:

2

I'm playing around with the Win32::IE::Mechanize. I'm trying a script to automatically access six of my web-based email accounts. The script basically works but perl throws a kind of cryptic "Can't locate object method "warn" via package "sssself" (perhaps you forgot to load " sssself)" error. Despite the error, the script can still get the job done. But I want to get rid of it and understand why it is happening. The following is the script. Please kindly commment where I can improve the code. Thanks like always.

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();
}

I know something is wrong with the line

$mech->set_fields(%$account);

But how can I correct it? or should I just delete

warn $@ if $@;

and pretend there's nothing wrong?

Any comments are welcome :)

UPDATE

Thank you, @daotoad, for cleaning up of my ugly code :) I think the nested structure is much more maintainable and nice on the eyes.

and thank you, @Eric, for pointing me to a better version of the module in question :)

Well, the thing is when Win32::IE:Mechanize 0.009 gives the following cryptic error message

Can't locate object method "warn" via package "sssself" (perhaps you forgot to l oad "sssself"?) at C:/Perl/site/lib/Win32/IE/Mechanize.pm line 971.

the 0.009_17 Dev Release gives me some very very meaningful message:

No inputcontrol by the name 'Username' at E:\mailme.pl line 33

With this error message in mind, I checked the source file of the login page and it has turned out that the field id should be "UserName", instead of "Username".

So I fixed my problem :) Thank you guys!

+2  A: 

I don't have time to give you are really good answer ATM, but here's a clean up of the code. Take a look at the comments. If you have any questions about what I did or why, just comment below and I'll update the question.

#!/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";
    };
}
daotoad
@daotaod, thanks for the cleaning up of my ugly code. Thanks, I really appreciate it :)
Mike
@daotoad, I'm trying to figure out why "Form failed" when it looks like nothing is wrong there and most importantly why when "Form failed", I can still access my mailboxes using the supposedly "failed form".
Mike
@daotaod, maybe it's a bug in IE::Mechanize?
Mike
+4  A: 

It appears that there is an error in Win32::IE::Mechanize version 0.009. There is a developer release 0.009_17 that may work better. I haven't tested it, but at least the 'sssself' is fixed. If IE isn't a requirement, there is also WWW::Mechanize::Firefox and WWW::Mechanize if the browser isn't needed.

Eric Strom
FWIW the "new" development release of Win32::IE::Mechanize is nearly 5 years old, so don't expect it to go stable anytime soon :)
hobbs