gpt4 book ai didi

Perl WWW::Mechanize 作为子类;无法保持登录到抓取的网站

转载 作者:行者123 更新时间:2023-12-02 02:26:16 25 4
gpt4 key购买 nike

我有一个使用 Perl WWW::Mechanize 的简单登录脚本。我正在编写登录 Moodle 的脚本.当我只是将登录步骤作为程序步骤执行时,它就起作用了。例如(假设“$site_url”、USERNAME 和 PASSWORD 已正确设置):

#THIS WORKS
$updater->get("http://".$site_url."/login/index.php");
$updater->form_id("login");
$updater->field('username', USERNAME);
$updater->field('password', PASSWORD);
$updater->click();
$updater->get("http://".$site_url."/");
print $updater->content();

当我尝试将这些步骤封装在 WWW:Mechanize 的子类中时,get() 和 content() 以及其他方法似乎有效,但登录站点却无效。我感觉它与可变范围有关,但我不知道如何解决它。

示例(失败):

my $updater = new AutoUpdater( $site_url, USERNAME, PASSWORD );
$updater->do_login();

{
package AutoUpdater;
use base qw( WWW::Mechanize );

sub new {
my $class = shift;
my $self = {
site_url => shift,
USERNAME => shift,
PASSWORD => shift,
};
bless $self, $class;
return $self;
}

sub do_login {
my $self = shift;
$self->get("http://".$site_url."/");
$self->get("http://".$site_url."/login/index.php");
$self->form_id("login");
$self->field("username", $self->{USERNAME});
$self->field("password", $self->{PASSWORD});
$self->click();
$self->get("http://".$site_url."/");
print $self->content();
}
}

这失败了。 “失败”意味着它没有登录。不过它确实抓取了网页,我可以操作 HTML 数据。它只是不登录。耶! (是的,“yargh”是必要的)

谢谢!

最佳答案

修改后的版本:

use strict;
use warnings;

my $updater = AutoUpdater->new( $site_url, USERNAME, PASSWORD );
$updater->do_login();

{
package AutoUpdater;
use parent qw( WWW::Mechanize );

sub new {
my $class = shift;

my $self = $class->SUPER::new();

$self->{AutoUpdater} = {
site_url => shift,
USERNAME => shift,
PASSWORD => shift,
};

return $self;
}

sub do_login {
my $self = shift;
my $data = $self->{AutoUpdater};

$self->get("http://$data->{site_url}/login/index.php");
$self->form_id("login");
$self->field("username", $data->{USERNAME});
$self->field("password", $data->{PASSWORD});
$self->click();
$self->get("http://$data->{site_url}/");
print $self->content();
}
} # end package AutoUpdater

一些注意事项:

您应该始终使用 strictwarnings帮助您发现错误。

不鼓励使用间接对象语法。使用 Class->new 而不是 new Class

base pragma 有一些不良影响,出于向后兼容性原因无法修复。 parent pragma 是为了取代它而开发的。

您的大问题是 Perl 不会自动初始化基类。如有必要,您必须显式调用 $class->SUPER::new

您的另一个大问题是了解如何处理对象实例数据。大多数 Perl 对象都是散列引用,您可以使用散列引用语法访问实例数据。当对一个我没有写的类进行子类化时,我喜欢使用第二个 hashref 来避免与父类发生冲突。请记住,您正在与基类共享对象。如果您的子类使用 site_url 字段,然后基类的后续版本开始使用 site_url 做其他事情,您的代码将突然中断,原因不明。通过在基对象 hashref 中仅使用一个键(以及基类不太可能开始使用的键),您可以最大限度地减少 future 损坏的可能性。

同时 Moose为 OO Perl 编程提供了一些不错的功能,如果您只是编写非 Moose 类的相当简单的子类,最好避免使用它。

关于Perl WWW::Mechanize 作为子类;无法保持登录到抓取的网站,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5861968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com