Как можно избавиться от ошибки «Не удается найти метод объекта» warn »через пакет« sssself »в IE :: Mechanize? - PullRequest
3 голосов
/ 27 февраля 2010

Я играю с Win32 :: IE :: Mechanize. Я пытаюсь сценарий для автоматического доступа к шести из моих учетных записей электронной почты в Интернете. Сценарий в основном работает, но Perl выдает своего рода загадочную ошибку «Не удается найти метод объекта» warn »через пакет« 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 $@;

и делать вид, что в этом нет ничего плохого?

Любые комментарии приветствуются:)

UPDATE

Спасибо, @daotoad, за очистку моего уродливого кода :) Я думаю, что вложенная структура гораздо удобнее в обслуживании и приятна на глаз.

и спасибо, @Eric, за указание на лучшую версию рассматриваемого модуля:)

Хорошо, дело в том, что Win32 :: IE: Mechanize 0.009 выдает следующее загадочное сообщение об ошибке

Не удается найти метод объекта "warn" через пакет "sssself" (возможно, вы забыли чтобы я "sssself"?) в C: /Perl/site/lib/Win32/IE/Mechanize.pm линия 971.

релиз разработчика 0.009_17 дает мне очень и очень значимое сообщение:

Нет ввода управления по имени «Имя пользователя» по E: \ mailme.pl, строка 33

Имея это в виду сообщение об ошибке, я проверил исходный файл страницы входа в систему и оказалось, что идентификатор поля должен быть «Имя пользователя», а не «Имя пользователя».

Так что я исправил свою проблему :) Спасибо, ребята!

Ответы [ 2 ]

4 голосов
/ 27 февраля 2010

Похоже, что ошибка в Win32 :: IE :: Mechanize версии 0.009. Существует версия для разработчиков 0.009_17 , которая может работать лучше. Я не проверял это, но по крайней мере «я» исправлено. Если IE не является обязательным требованием, есть также WWW::Mechanize::Firefox и WWW::Mechanize, если браузер не нужен.

2 голосов
/ 27 февраля 2010

У меня нет времени, чтобы дать вам действительно хороший ответ, банкомат, но здесь приведу код в порядок. Посмотрите на комментарии. Если у вас есть какие-либо вопросы о том, что я сделал или почему, просто прокомментируйте ниже, и я обновлю вопрос.

#!/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";
    };
}
...