Während die Kommentare von ThisSuitIsBlackNot genau richtig sind, gibt es eine ziemlich einfache Möglichkeit, dies programmgesteuert ohne JS überhaupt zu tun. Sie brauchen nicht einmal WWW :: Mechanize.
Ich habe Web::Scraper verwendet, um alle Dateien zu finden. Wie du gesagt hast, sind die Formularwerte da. Es geht darum, sie auszukratzen. WWW :: Mechanize ist gut im Navigieren, aber nicht sehr gut im Scraping. Die Oberfläche von Web :: Scraper ist dagegen wirklich einfach.
Sobald wir die Dateien haben, müssen wir nur eine POST-Anfrage mit den korrekten Formularwerten senden. Dies ist sehr ähnlich zu WWW :: Mechanizes submit_form
. In der Tat ist WWW :: Mechanize ein LWP::UserAgent unter der Haube, und alles, was wir brauchen, ist eine Anfrage, also können wir es direkt verwenden.
Die :content_file
option auf der post
method sagt es, um die Antwort in eine Datei zu setzen. Es wird mit der ZIP-Datei das Richtige tun und es automatisch als Binärdatei schreiben.
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
);
}
Sobald Sie dies ausführen, haben Sie alle Dateien im Verzeichnis Ihres Skripts. Es wird einen Moment dauern und es gibt keine Ausgabe, aber es funktioniert.
Sie müssen sicherstellen, dass der Absenden-Button im Formular enthalten ist.
Da Sie lernen wollten, wie man so etwas macht, habe ich es etwas dynamisch gebaut. Die Formularaktion wird ebenfalls gekratzt, sodass Sie sie in ähnlichen Formularen wiederverwenden können, die dieselben Formularnamen verwenden (oder zu einem Argument machen), und Sie müssen sich nicht um die Formularaktion kümmern. Das Gleiche könnte auch mit der Schaltfläche "Senden" durchgeführt werden, aber Sie müssten sowohl das name
als auch das value
Attribut verwenden.
Ich wiederhole was ThisSuitIsBlackNot said in their comment though: Scraping einer Website kommt immer mit dem Risiko, dass es später ändert! Für eine einmalige Sache, die egal ist, wenn Sie dies als ein cronjob einmal jährlich ausführen möchten, könnte es nächstes Jahr schon scheitern, weil sie schließlich ihre Website aktualisiert haben, um ein bisschen moderner zu sein.
Deaktivieren Sie JavaScript in Ihrem Browser und Sie werden sehen, dass die Seite ohne sie nutzlos ist, also ist WWW :: Mechanize out. Anstatt WWW :: Mechanize :: Firefox zu verwenden, sollten Sie jedoch prüfen, ob die Daten über eine API verfügbar sind. das ist fast immer eine bessere Wahl als das Kratzen. [Hier] (http://developer.dol.gov/) ist die Hauptseite des Department of Labor API. – ThisSuitIsBlackNot
Ja, mir ist bewusst, dass die Seite ohne JavaScript aktiviert ist.Der Quellcode ist jedoch immer noch da und ich bin gespannt, warum eine POST-Anfrage mit den entsprechenden Feldern, die mit der Anfrage gesendet wurden, nicht dazu führt, dass der Server das Dokument sendet, insbesondere mit WWW :: Mechanize :: Firefox. – StevieD
Schauen Sie sich die Quelle an, in der JS deaktiviert ist: Es gibt kein '' Element, also wird 'submit_form' natürlich nichts tun. Da W :: M :: F nicht funktioniert, haben Sie keinen 'submitButton'-Parameter festgelegt, und es gibt andere Header, die Sie möglicherweise nicht festgelegt haben. Aber genau das sind APIs auch. Sie sollten nicht in den Bauch einer Webseite blättern, die für den menschlichen Konsum gemacht wurde, weil sie sich jederzeit ändern und Ihren Code auf eine Million verschiedene Arten brechen könnte. – ThisSuitIsBlackNot