Perl 使用WWW::Mechanize保存文件

Perl 使用WWW::Mechanize保存文件,perl,web-scraping,www-mechanize,Perl,Web Scraping,Www Mechanize,我正试图通过编程从这个页面中删除文件:(是的,手动下载可能会更快,但我想学习如何做到这一点) 我有以下代码尝试对其中一个文件进行此测试: #!/usr/bin/perl use strict; use warnings; use WWW::Mechanize; my $mech = WWW::Mechanize->new; $mech->get( 'https://olms.dol-esa.gov/query/getYearlyData.do' ); print $mech-&

我正试图通过编程从这个页面中删除文件:(是的,手动下载可能会更快,但我想学习如何做到这一点)

我有以下代码尝试对其中一个文件进行此测试:

#!/usr/bin/perl
use strict;
use warnings;
use WWW::Mechanize; 

my $mech = WWW::Mechanize->new;

$mech->get( 'https://olms.dol-esa.gov/query/getYearlyData.do' );
print $mech->uri();
$mech->submit_form( with_fields => { selectedFileName => '/filer/local/cas/YearlyDataDump/2000.zip' } );
当我运行代码时,什么也没发生。没有下载任何内容。考虑到javascript可能是问题所在,我还尝试了使用WWW::Mechanize::Firefox的相同代码。同样,当我运行代码时,什么也没有发生

我也看不到文件的路径。它可能在一些javascript中被掩盖了


那么获取这些文件的最佳方式是什么?有没有可能在没有javascript的情况下获取它们?

虽然ThisSuitesBlacknot的注释不存在,但有一种非常简单的方法可以通过编程实现,而不必使用JS。您甚至不需要WWW::Mechanize

我曾经找到过所有的文件。正如您所说,表单值就在那里。这是把它们刮出来的问题。WWW::Mechanize擅长导航,但不太擅长抓取。另一方面,Scraper的界面非常简单

一旦我们有了这些文件,我们所需要做的就是提交一个带有正确表单值的POST请求。这与WWW::Mechanize的
提交表单
非常相似。事实上,WWW::Mechanize是一个秘密,我们只需要一个请求,所以我们可以直接使用它

上的命令将响应放入文件中。它将对ZIP文件执行正确的操作,并自动将其作为二进制文件写入

use strict;
use warnings;
use LWP::UserAgent;
use Web::Scraper;
use URI;

# build a Web::Scraper to find all files on the page
my $files = scraper {
    process 'form[name="yearlyDataForm"]',    'action'  => '@action';
    process 'input[name="selectedFileName"]', 'files[]' => '@value';
};

# get the files and the form action
my $res = $files->scrape( URI->new('https://olms.dol-esa.gov/query/getYearlyData.do') );

# use LWP to download them one by one
my $ua = LWP::UserAgent->new;
foreach my $path ( @{ $res->{files} } ) {

    # the file will end up relative to the current working directory (.)
    ( my $filename ) = ( split '/', $path )[-1];

    # the submit is hardcoded, but that could be dynamic as well
    $ua->post(
        $res->{action},
        { selectedFileName => $path, submitButton => 'Download' },
        ':content_file' => $filename # this downloads the file
    );
}
一旦运行此脚本,脚本目录中就有了所有文件。这需要一段时间,没有输出,但它可以工作

您需要确保表单中包含submit按钮

既然你想学习如何做这样的事情,我已经建立了它稍微动态。表单操作也会被删除,因此您可以在使用相同表单名称(或将其作为参数)的类似表单上重用它,而不必关心表单操作。同样的事情也可以通过submit按钮完成,但是您需要同时获取
名称
属性


不过我要重复一下:抓取一个网站总是伴随着以后更改的风险对于一件无关紧要的一次性事情,如果你想每年将其作为cronjob运行一次,那么明年它可能已经失败了,因为他们最终更新了他们的网站,使其更加现代化。

在浏览器中禁用JavaScript,你会发现没有它,页面将毫无用处,因此WWW::Mechanize已过时。但是,不要使用WWW::Mechanize::Firefox,而是应该查看数据是否可以通过API访问;这几乎总是比刮擦更好的选择。是劳工部API的主页。是的,我知道页面在没有打开javascript的情况下显示为空白。但是,源代码仍然存在,我很好奇,为什么带有相应字段的POST请求不会导致服务器发送文档,特别是在WWW::Mechanize::Firefox中。查看禁用JS的源代码:没有
元素,所以自然地,
submit\u form
不会做任何事情。至于W::M::F不工作,您没有设置
submitButton
参数,并且可能需要设置其他未设置的头。但同样,这正是API的用途;你不应该在一个供人使用的网页中到处探索,因为它随时都可能改变,并以无数种不同的方式破坏你的代码。非常巧妙。我熟悉Web::Scraper,但没有想到使用它来提取必要的表单元素。我也没有想过像那样使用LWP::UserAgent。我学到了我一直在寻找的东西。谢谢是的,我很清楚刮擦的局限性。这更像是一次学术练习,所以我可以提高我的技能。@StevieD很高兴我能帮忙。:)