将机械化浏览器传递给子例程(带有 WWW::Mechanized 的 Perl)

发布于 2024-11-08 19:39:35 字数 2393 浏览 3 评论 0原文

我仍在学习 Perl,因此对缺乏技术术语知识和一般新手表示歉意。

我正在尝试编写一个脚本来登录我的课程作品帐户并下载所有文件。我只能停留大约一个小时,直到我必须重新登录,所以我想在子例程中完成登录工作,这样根据时间我可以调用它并重新登录并继续爬行。我的问题是我希望能够在子例程和主代码之间来回传递浏览器(?关于术语,请参阅下面的示例,它会更有意义)。

这是我到目前为止所拥有的,但它不起作用:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url,$browser) = @_;
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
    return $browser;
}

这表示我无法在 $browser -> 上“在未定义的值上调用方法'get'”。获取($url);。所以我猜测在主代码中初始化浏览器不起作用(因为它没有传递给子例程)Y/N?

好吧,很酷,然后我尝试在子例程本身中执行此操作,如下所示:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url) = @_;
    my $browser = WWW::Mechanize->new();
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
    return $browser;
}

这次我收到以下错误消息:“在 C:/Perl64/lib/HTTP/Response.pm 第 93 行缺少基本参数”

因此,我删除了行在子例程中直到它工作为止,发现它编译时如下所示:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url) = @_;
    my $browser = WWW::Mechanize->new();
#   $browser -> get($url);
#   $browser -> form_name('theform');
#   $browser -> field ('username' => $user);
#   $browser -> field ('password' => $pass);
#   $browser -> click ('log in');
    return $browser;
}

但它显然只是返回垃圾。

我认为问题是,正如我所说,试图将浏览器对象传递给子例程,因为我不认为它只是一个标量(因为我可以从中获取“内容”之类的东西),但我实际上真的没有把握。我也很困惑,因为当我在子程序中初始化它时,我仍然遇到问题!我还尝试将 $browser 设为全局变量,但在两个代码中都遇到了相同的错误。显然我在这里遗漏了一些东西。

预先感谢所有经历过它的人,我知道这可能是一个非常简单的答案,这有点冗长,但我的经验不足。

I am still learning Perl so apologies on lack of technical term knowledge and general newbie-ness.

I am trying to write a script to log into my course works account and download all the files. I can only stay in for about an hour until I have to re-log in, so I want to do the log-in work in a subroutine so that way depending on the time I can just call it and log-back in and continue crawling. My problem is that I want to be able to pass the browser (? on terminology, see example below it will make more sense) back and forth between the subroutine and main code.

This is what I have so far and it does not work:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url,$browser) = @_;
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
    return $browser;
}

This says I cannot "call method 'get' on an undefined value" at $browser -> get($url);. So I'm guessing that initializing the browser in the main code didn't work (as in it was not passed to the subroutine) Y/N??

Ok cool so then I tried to do it in the subroutine itself as follows:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url) = @_;
    my $browser = WWW::Mechanize->new();
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
    return $browser;
}

This time I get the following error message: "Missing base argument at C:/Perl64/lib/HTTP/Response.pm line 93"

So, I deleted lines in the subroutine until it worked, and found out that it compiles when it looks as follows:

use strict;
use WWW::Mechanize;

login();
my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $response = login ($username,$password,$url,$browser);
print $response->content;

sub login {
    my ($user,$pass,$url) = @_;
    my $browser = WWW::Mechanize->new();
#   $browser -> get($url);
#   $browser -> form_name('theform');
#   $browser -> field ('username' => $user);
#   $browser -> field ('password' => $pass);
#   $browser -> click ('log in');
    return $browser;
}

but it obviously just returns garbage.

I think the problem is, as I said, trying to pass the browser object to the subroutine as I don't think it is simply a scalar (because I can get things like "content" from it), but I'm actually really not sure. I am also confused because when I initialize it in the subroutine I still get a problem!!????? I also tried to make $browser a global variable, but I get the same errors in both codes. Obviously I am missing something here.

Thanks in advance to all who get through it I know its a little long-winded for probably a really simple answer that hits at my inexperience.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦醒时光 2024-11-15 19:39:35

您的第一次登录调用不提供浏览器、用户名等。

如果您在整个脚本中只需要一个 Mechanize 实例(并且将使用同一用户登录),则可以依赖全局变量。

use strict;
use WWW::Mechanize;

my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

login();
print $browser->$response->content;

sub login {
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
}

或者更好的是,每次都将数据传递给登录:

use strict;
use WWW::Mechanize;

my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

login ($username,$password,$url);
print $browser->$response->content;

sub login {
    my ($user,$pass,$url) = @_;
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
}

如果您每次都想要一个新的 Mechanize 实例,请在登录中实例化它并返回它。

Your first call to login provides no browser, username etc.

If you need but one instance of Mechanize (and will login with the same user) throughout the script, you could rely on global variables.

use strict;
use WWW::Mechanize;

my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

login();
print $browser->$response->content;

sub login {
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
}

Or better, pass your data to login each time:

use strict;
use WWW::Mechanize;

my $username = 'username';
my $password = 'password';
my $url = 'website url';

my $browser = WWW::Mechanize->new();

login ($username,$password,$url);
print $browser->$response->content;

sub login {
    my ($user,$pass,$url) = @_;
    $browser -> get($url);
    $browser -> form_name('theform');
    $browser -> field ('username' => $user);
    $browser -> field ('password' => $pass);
    $browser -> click ('log in');
}

If you want a new Mechanize instance each time, instance it in login and return it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文