Я пытаюсь загрузить более 1 млн страниц (URL-адреса заканчиваются идентификатором последовательности). Я реализовал своего рода многоцелевой менеджер загрузки с настраиваемым количеством потоков загрузки и одним потоком обработки. Загрузчик загружает файлы пакетами:
curl = Curl::Easy.new
batch_urls.each { |url_info|
curl.url = url_info[:url]
curl.perform
file = File.new(url_info[:file], "wb")
file << curl.body_str
file.close
# ... some other stuff
}
Я попытался загрузить образец на 8000 страниц. При использовании приведенного выше кода я получаю 1000 за 2 минуты. Когда я пишу все URL-адреса в файл и делаю это в оболочке:
cat list | xargs curl
Я прочитал все 8000 страниц за две минуты.
Дело в том, что мне нужно, чтобы это было в коде ruby, потому что есть другой код мониторинга и обработки.
Я пытался:
- Curl::Multi - как-то быстрее, но пропускает 50-90% файлов (не скачивает их и не дает причину/код)
- несколько потоков с Curl::Easy - примерно такая же скорость, как и однопоточная
Почему повторное использование Curl::Easy медленнее, чем последующие вызовы curl из командной строки, и как я могу сделать это быстрее? Или что я делаю не так?
Я бы предпочел исправить свой код менеджера загрузки, чем делать загрузку для этого случая по-другому.
До этого я вызывал командную строку wget, которой я предоставил файл со списком URL-адресов. Однако не все ошибки были обработаны, также было невозможно указать выходной файл для каждого URL-адреса отдельно при использовании списка URL-адресов.
Теперь мне кажется, что лучшим способом было бы использовать несколько потоков с системным вызовом команды curl. Но зачем, если я могу напрямую использовать Curl в Ruby?
Код для менеджера загрузки находится здесь, если он может помочь: Диспетчер загрузок (игрался с тайм-аутами, не устанавливая его на разные значения, не помогло)
Любые подсказки приветствуются.
cat list | xargs curl
передает много URL-адресов Curl в командной строке, а не по одному, поэтому Curl извлекает много URL-адресов одновременно. Вы можете сделать это в Ruby достаточно легко, но вам нужно сравнивать яблоки с яблоками и использовать HTTPClient или Typhoeus. - person the Tin Man   schedule 08.09.2012