簡體   English   中英

使用 WWW::Mechanize 保存文件

[英]Saving files with WWW::Mechanize

我正在嘗試以編程方式從此頁面抓取文件: https : //olms.dol-esa.gov/query/getYearlyData.do (是的,手動下載它們可能會更快,但我想了解如何執行此操作)。

我有以下代碼嘗試在其中一個文件上嘗試作為測試:

#!/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 的情況下獲得它們?

雖然 ThisSuitIsBlackNot 的評論是正確的,但有一種相當簡單的方法可以在不使用 JS 的情況下以編程方式執行此操作。 你甚至不需要 WWW::Mechanize。

我使用Web::Scraper來查找所有文件。 正如您所說,表單值就在那里。 這是把它們刮掉的問題。 WWW::Mechanize 擅長導航,但不太擅長抓取。 另一方面,Web::Scraper 的界面非常簡單。

一旦我們有了文件,我們需要做的就是提交一個帶有正確表單值的 POST 請求。 這與 WWW::Mechanize 的submit_form非常相似。 實際上,WWW::Mechanize 背后是一個LWP::UserAgent ,我們只需要一個請求,就可以直接使用它。

post方法上的:content_file選項告訴它將響應放入文件中。 它會對 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
    );
}

運行此命令后,您將擁有腳本目錄中的所有文件。 這將需要一點時間並且沒有輸出,但它可以工作。

您需要確保在表單中包含提交按鈕。

既然你想學習如何做這樣的事情,我就稍微動態地構建了它。 表單操作也會被刮掉,因此您可以在使用相同表單名稱的類似表單上重用它(或將其作為參數),而您不必關心表單操作。 同樣的事情也可以用提交按鈕來完成,但你需要同時獲取namevalue屬性。

不過,我將重復ThisSuitIsBlackNot 在他們的評論中所說的話抓取網站總是伴隨着以后更改的風險! 對於一次無關緊要的事情,如果您想每年將其作為 cronjob 運行一次,那么明年可能已經失敗,因為他們最終更新了他們的網站,使其更加現代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM