使用Perl控制Firefox

更新 在0.55版本中,Firefox移除了允许MozRepl工作的功能。
我一直在尝试WWW::Mechanize::Firefox。它就像LWP后端WWW::Mechanize,但是有一个浏览器来完成所有工作。我不再需要在Perl中完成所有工作,我可以将其用作粘合语言。
有时WWW::Mechanize、LWP::UserAgent或Mojo::UserAgent都不够用。对于基本的网络抓取和自动化,它们表现良好,但无法处理需要JavaScript的任何事情。有些人使用SpiderMonkey(有多个Perl接口)很幸运,但这仍然不是完整的浏览器环境。
在开始之前,您需要一个带有Firefox浏览器(或其分支之一)和MozRepl插件的浏览器,该插件提供了一个交互式JavaScript控制台,您可以通过telnet进入。一旦激活,您就可以连接到控制台并控制浏览器。
我必须了解JavaScript才能直接控制Firefox。我可以telnet到MozRepl服务器并发送命令。这比我想做的要多一些工作。
但是,我不会直接控制Firefox,因为我会让一些Perl模块来帮我完成这个任务。WWW::Mechanize::Firefox的基本接口与WWW::Mechanize相同
#!/usr/local/perls/perl-5.20.0/bin/perl
use v5.10;
use WWW::Mechanize::Firefox;
my $mech = WWW::Mechanize::Firefox->new;
$mech->autoclose_tab( 0 );
$mech->get( 'http://www.perltricks.com' );
foreach my $link ( $mech->links ) {
state $count = 0;
say $count++, ": ", $link->url;
}
我获取PerlTricks主页上的链接列表
0: http://perltricks.com/favicon.ico
1: http://perltricks.com/feed/atom
2: http://perltricks.com/feed/rss
3: http://perltricks.com/css/bootstrap.min.css
4: http://perltricks.com/css/carousel.css
5: http://perltricks.com/css/perltricks.css
6: https://twitter.com/intent/follow?screen_name=perltricks
7: http://perltricks.com/feed/rss
...
这甚至还不是最好的部分。
执行JavaScript
由于我连接到一个JavaScript终端,我可以评估JavaScript代码。eval返回结果及其类型
use v5.10;
use WWW::Mechanize::Firefox;
my $mech = WWW::Mechanize::Firefox->new;
$mech->autoclose_tab( 0 );
my( $result, $type ) = $mech->eval( '2+2' );
say "2+2 is $result (type $type)";
2+2 is 4 (type number)
这评估了JavaScript在其自己的上下文中,这对我不太有趣。我想与网页的某些部分进行交互和控制。为此,我使用eval_in_page。它将JavaScript与当前选项卡中正在进行的所有内容一起运行,包括它已加载的所有JavaScript代码。以下是一个使用StackExchange JavaScript将视图从桌面模式切换到移动模式的示例
use v5.10;
use WWW::Mechanize::Firefox;
my $mech = WWW::Mechanize::Firefox->new;
$mech->autoclose_tab( 0 );
$mech->get( 'http://www.stackoverflow.com/' );
sleep 5;
$mech->eval_in_page( 'StackExchange.switchMobile("on")' );
当我运行这个时,屏幕从完整站点切换到移动站点。
一些问题
尽管这种方法的缺点几乎都不是来自Perl。如果我想自动化需要大量请求或运行时间长的任务,Firefox可能会出现问题。随着时间的推移,它的内存占用增加,导致性能下降和崩溃。有时与控制台的联系会中断,导致我的程序崩溃。
因此,我将WWW::Mechanize::Firefox的使用限制在需要JavaScript的问题部分。我可以提取所需的信息,然后使用Mojo::UserAgent处理其他部分。
类似解决方案
WWW::Mechanize::Firefox并不是做这类事情的唯一方法。Rob Hammond在blogs.perl.org上发布了一篇关于PhantomJS的文章,关于WWW::WebKit有一些评论。曾经有一个Win32::IE::Mechanize,但显然它在IE 8中不起作用。Selenium和Test::WWW::Selenium是另一个我可以使用的工具,但它更适合浏览器验收测试和重放。
加入关于这篇文章的Perl subreddit上的讨论!
更新: 最后一段更新以包含Selenium参考。2014-12-09
本文最初发布在 PerlTricks.com 上。
标签
brian d foy
brian d foy 是一名 Perl 训练师和作家,同时也是 Perl.com 的资深编辑。他是《精通 Perl》、《Mojolicious Web 客户端》、《学习 Perl 练习》的作者,以及《Perl 编程》、《学习 Perl》、《中级 Perl》和《有效 Perl 编程》的合著者。
浏览他们的文章
反馈
这篇文章有什么问题吗?请在 GitHub 上提交一个 issue 或 pull request 来帮助我们。