Загрузки в Firefox с использованием Perl WWW :: Mechanize :: Firefox

У меня есть список URL-адресов PDF-файлов, которые я хочу загрузить, с разных сайтов.

В моем firefox я выбрал возможность сохранять файлы PDF непосредственно в определенную папку.

Я планировал использовать WWW :: Mechanize :: Firefox в perl для загрузки каждого файла (в списке - один за другим) с помощью Firefox и переименования файла после загрузки.

Для этого я использовал следующий код:

    use WWW::Mechanize::Firefox;
    use File::Copy;

    # @list contains the list of links to pdf files
    foreach $x (@list) {
        my $mech = WWW::Mechanize::Firefox->new(autoclose => 1);
        $mech->get($x);  #This downloads the file using firefox in desired folder

        opendir(DIR, "output/download");
        @FILES= readdir(DIR);
        my $old = "output/download/$FILES[2]";
        move ($old, $new);  # $new is the URL of the new filename
    }

Когда я запускаю файл, он открывает первую ссылку в Firefox, и Firefox загружает файл в желаемый каталог. Но после этого «новая вкладка» не закрывается, файл не переименовывается, а код продолжает работать (например, возник бесконечный цикл), и никакие другие файлы не загружаются.

Что здесь происходит? Почему код не работает? Как закрыть вкладку и заставить код читать все файлы в списке? Есть ли альтернативный способ загрузки?


person Pawan Samdani    schedule 11.03.2014    source источник
comment
Это не тот код, который вы используете. В этом коде есть несколько очевидных ошибок, которые означают, что он никогда не запустится. (1) Вы выполняете цикл с $x, но пытаетесь получить неопределенное значение $link. (2) Вы предполагаете, что $FILES[2] содержит только что загруженный файл. (3) В Perl нет встроенного move sub - он называется rename.   -  person Richard Huxton    schedule 11.03.2014
comment
$link была опечаткой при редактировании вопроса, это $x указывает на ссылки. Я проверил, что $FILES[2] указывает на файл, так как в моем каталоге только 1 файл, а первые 2 элемента массива - это '.' и '..'. А move - это метод в File :: Copy. Я внес изменения в вопрос   -  person Pawan Samdani    schedule 11.03.2014
comment
Предполагая, что вы действительно протестировали вторую половину и подтвердили, что команда, которая зависает, является get (проще всего, вставив печать после нее), я бы предположил, что все, что get использует, чтобы определить, все ли загружено, плохо работает с вашим автоматическим скачивание. Вы можете попробовать get_local и / или использовать параметр content_file для загрузки файла вместо некоторого автоматического поведения Firefox, о котором ваш скрипт не знает. Или вы откажетесь от firefox и просто используете WWW :: Mechanize, не прибегая к причудливым конфетам в виде удаленного управления каким-нибудь браузером, за которым вы можете наблюдать.   -  person DeVadder    schedule 11.03.2014
comment
Я не могу использовать WWW :: Mechanize, так как мне нужно открывать ссылки в браузере, поскольку доступ к файлам pdf осуществляется через прокси-сервер вне кампуса (EZProxy), который требует аутентификации. Это не работает только с Mechanize. get_local метод заключается в загрузке локальных файлов. content_file находится в WWW :: Mechanize, а не в WWW :: Mechanize :: Firefox   -  person Pawan Samdani    schedule 11.03.2014
comment
Вы правы насчет get_local. Но хотя WWW :: Mechanize, вероятно, намного сложнее, он может использовать прокси. Однако я ясно вижу :content_file как вариант для get в документации Mechanize :: Firefox. И я все же буду утверждать, что лучше делать все из сценария вместо того, чтобы Firefox автоматически загружал ссылки в формате pdf. Кроме того, Mechanize :: Firefox возвращает поддельные объекты HTTP :: Response, поэтому ->content также может работать. Наконец, если вы никуда не торопитесь, вы можете добавить достаточно большой таймаут к вызову get, игнорируя тот факт, что он не знает, когда это будет сделано.   -  person DeVadder    schedule 11.03.2014
comment
Спасибо @DeVadder. Я понял, что get, возможно, ожидает ответа на загрузку страницы из Firefox, чтобы продолжить. Поскольку Firefox загружал файлы, страница не загружалась. Таким образом, я установил get, чтобы он не ждал ответа, и добавил тайм-аут 60 секунд. И это сработало.   -  person Pawan Samdani    schedule 12.03.2014


Ответы (2)


Решил проблему.

Функция,

$mech->get() 

ожидает, когда Firefox запустит событие 'DOMContentLoaded' при загрузке страницы. Поскольку я настроил Firefox на автоматическую загрузку файлов, страница не загружалась. Таким образом, событие «DOMContentLoaded» никогда не запускалось. Это привело к паузе в моем коде.

Я установил функцию, не дожидаясь загрузки страницы, используя следующую опцию

$mech->get($x, synchronize => 0);

После этого я добавил 60-секундную задержку, чтобы Firefox мог загрузить файл до выполнения кода.

sleep 60;

Таким образом, мой окончательный код выглядит как

use WWW::Mechanize::Firefox;
use File::Copy;

# @list contains the list of links to pdf files
foreach $x (@list) {
    my $mech = WWW::Mechanize::Firefox->new(autoclose => 1);

    $mech->get($x, synchronize => 0);
    sleep 60;

    opendir(DIR, "output/download");
    @FILES= readdir(DIR);
    my $old = "output/download/$FILES[2]";
    move ($old, $new);  # $new is the URL of the new filename
}
person Pawan Samdani    schedule 12.03.2014

Если я вас правильно понял, у вас есть ссылки на актуальные файлы pdf. В этом случае WWW :: Mechanize, скорее всего, проще, чем WWW :: Mechanize :: Firefox. На самом деле, я думаю, что это почти всегда так. С другой стороны, наблюдать за работой браузера, безусловно, круче.

use strict;
use warnings;

use WWW::Mechanize;

# your code here
# loop

    my $mech = WWW::Mechanize->new();    # Could (should?) be outside of the loop.
    $mech->agent_alias("Linux Mozilla"); # Optionally pretend to be whatever you want.

    $mech->get($link);
    $mech->save_content("$new");

#end of the loop

Если это совсем не то, что вы хотели, моя история прикрытия будет заключаться в том, что я не хотел нарушать свою 666 репутацию!

person DeVadder    schedule 11.03.2014
comment
Я попытался установить прокси в WWW :: Mechanize, но он не работает, так как требует, чтобы страница всегда была открыта для аутентификации прокси. Даже если я оставлю страницу аутентификации открытой в Firefox и использую WWW :: Mechanize, это не сработает. Таким образом, мне нужен WWW :: Mechanize :: Firefox. - person Pawan Samdani; 12.03.2014