3

私は Win32::IE::Mechanize で遊んでいます。6 つの 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 が次の不可解なエラー メッセージを表示する場合です。

C:/Perl/site/lib/Win32/IE/Mechanize.pm の 971 行目で、パッケージ "sssself" を介してオブジェクト メソッド "warn" を見つけることができません (おそらく "sssself" をロードするのを忘れていましたか?)。

0.009_17 Dev リリースは、非常に意味のあるメッセージを私に与えてくれます。

E:\mailme.pl 行 33 に「Username」という名前による入力制御がありません

このエラー メッセージを念頭に置いて、ログイン ページのソース ファイルを確認したところ、フィールド ID は「Username」ではなく「UserName」であることが判明しました。

だから私は私の問題を修正しました:)みんなありがとう!

4

2 に答える 2

4

Win32::IE::Mechanize バージョン 0.009 にエラーがあるようです。開発者リリース 0.009_17の方が適切に機能する可能性があります。私はそれをテストしていませんが、少なくとも 'sssself' は修正されています。IE が必要でない場合は、ブラウザが不要な場合もWWW::Mechanize::Firefoxあります。WWW::Mechanize

于 2010-02-27T06:32:58.120 に答える
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";
    };
}
于 2010-02-27T03:14:51.883 に答える