Библиотека или инструмент для параллельного скачивания нескольких файлов
Я ищу библиотеку python или инструмент командной строки для параллельной загрузки нескольких файлов. Мое текущее решение заключается в том, чтобы загружать файлы последовательно, что медленно. Я знаю, что вы можете легко написать однопоточное решение на python, но я всегда сталкиваюсь с раздражающей проблемой при использовании потоковой передачи. Он предназначен для опроса большого количества XML-материалов с веб-сайтов.
Мои требования к решению:
- Должно прерываться. Ctrl + C должен немедленно прекратить все загрузки.
- Не должно быть никаких оставшихся процессов, которые вы должны убить вручную, используя kill, даже если сбой основной программы или исключение.
- Он также должен работать на Linux и Windows.
- Он должен повторять загрузки, быть устойчивыми к сетевым ошибкам и должным образом таймаутом.
- Должно быть разумно не забивать один и тот же сервер со 100+ одновременными загрузками, но ставить их в очередь разумно.
- Он должен обрабатывать важные коды статуса http, такие как 301, 302 и 304. Это означает, что для каждого файла он должен принимать значение Last-Modified как входное и загружать только, если он изменился с последнего раза.
- Предпочтительно, он должен иметь индикатор выполнения, или ему должно быть легко написать индикатор выполнения, чтобы он отслеживал ход загрузки всех файлов.
- Предпочтительно он должен использовать http keep-alive для максимизации скорости передачи.
Пожалуйста, не предлагайте, как я могу реализовать вышеуказанные требования. Я ищу готовое, проверенное сражения решение.
Я думаю, я должен описать, что я тоже хочу... У меня около 300 различных каналов передачи данных в виде файлов в формате XML, которые подаются от 50 поставщиков данных. Каждый файл имеет размер от 100 КБ до 5 МБ. Мне нужно часто их опроса (как раз в несколько минут), чтобы определить, есть ли у кого-то из них новые данные, которые мне нужно обработать. Поэтому важно, чтобы загрузчик использовал кеширование http для минимизации объема данных для извлечения. Очевидно, что он использует сжатие gzip.
Тогда большая проблема заключается в том, как использовать пропускную способность как можно эффективнее, не переступая границы. Например, один поставщик данных может считать его злоупотреблением, если вы открываете 20 одновременных подключений к своим фидам данных. Вместо этого может быть лучше использовать одно или два соединения, которые повторно используются для нескольких файлов. Или ваше собственное соединение может быть ограничено странными способами. Мой isp ограничивает количество поисков dns, которые вы можете сделать, чтобы какое-то кэширование DNS было приятным.
Ответы
Ответ 1
Вы можете попробовать pycurl, хотя интерфейс сначала непросто, но как только вы посмотрите на примеры, его не трудно понять. Я использовал его для получения 1000 веб-страниц параллельно в скудной linux-боксе.
- Вам не нужно иметь дело с потоками, поэтому он прекращается изящно, и никаких процессов не осталось.
- Он предоставляет опции для тайм-аута и обработки статуса http.
- Он работает как с linux, так и с окнами.
Единственная проблема заключается в том, что она обеспечивает базовую инфраструктуру (в основном, только слой python над превосходной библиотекой curl). Вам нужно будет написать несколько строк, чтобы получить нужные функции.
Ответ 2
Есть много вариантов, но будет сложно найти тот, который соответствует всем вашим потребностям.
В вашем случае попробуйте использовать этот подход:
- Создайте очередь.
- Поместите URL-адреса для загрузки в эту очередь (или "объекты конфигурации", содержащие URL-адрес и другие данные, такие как имя пользователя, целевой файл и т.д.).
- Создать пул потоков
- Каждый поток должен попытаться извлечь URL-адрес (или объект конфигурации) из очереди и обработать его.
Используйте другой поток для сбора результатов (т.е. другой очереди). Когда количество объектов результата == количество пометок в первой очереди, вы закончите.
Убедитесь, что вся связь идет через очередь или "объект конфигурации". Избегайте доступа к структурам данных, которые совместно используются потоками. Это должно сэкономить вам 99% проблем.
Ответ 3
Я не думаю, что такая полная библиотека существует, поэтому вам, вероятно, придется писать свои собственные. Я предлагаю взглянуть на gevent для этой задачи. Они даже предоставляют concurrent_download.py пример script. Затем вы можете использовать urllib2 для большинства других требований, таких как обработка кодов состояния HTTP и отображение процесса загрузки.
Ответ 4
Я бы предложил Twisted, хотя это не готовое решение, но предоставляет основные строительные блоки, чтобы получить каждую функцию, которую вы указали простым способом, и она не использует потоки.
Если вам интересно, ознакомьтесь со следующими ссылками:
В соответствии с вашими требованиями:
- Поддерживается из коробки
- Поддерживается из коробки
- Поддерживается из коробки
- Время ожидания поддерживается из коробки, другая обработка ошибок выполняется через отложенные
- Достигнуто легко, используя cooperators (пример 7)
- Поддерживается из коробки
- Не поддерживается, существуют решения (и их не так сложно реализовать)
- Не поддерживается, он может быть реализован (но он будет относительно тяжелым).
Ответ 5
В настоящее время есть отличные библиотеки Python, которые вы можете использовать - urllib3 и requests
Ответ 6
Попробуйте использовать aria2 через простой python subprocess.
Он предоставляет все требования из вашего списка, кроме 7, из коробки, и 7 легко писать.
aria2c имеет хороший интерфейс xml-rpc или json-rpc для взаимодействия с ним из ваших сценариев.
Ответ 7
Threading не является "полуподобным", если вы плохо программист. Наилучшим общим подходом к этой проблеме является модель производителя/потребителя. У вас есть один выделенный производитель URL-адресов и N выделенных потоков загрузки (или даже процессов, если вы используете модель многопроцессорности).
Как и во всех ваших требованиях, ВСЕ их можно выполнить с помощью обычной модели на основе python (да, даже поймав Ctrl + C - я это сделал).
Ответ 8
Соответствует ли urlgrabber вашим требованиям?
http://urlgrabber.baseurl.org/
Если это не так, вы можете подумать о добровольчестве, чтобы помочь ему закончить. Свяжитесь с авторами, Майклом Стэннером и Райаном Томайко.
Обновление: Google для параллельного wget дает, среди прочего, следующие:
http://puf.sourceforge.net/
http://www.commandlinefu.com/commands/view/3269/parallel-file-downloading-with-wget
Кажется, у вас есть выбор на выбор.
Ответ 9
Я использовал стандартные библиотеки для этого, urllib.urlretrieve
, чтобы быть точным. скачанные подкасты таким образом, через простой пул потоков, каждый из которых использует свой собственный выбор. Я сделал около 10 одновременных соединений, больше не должно быть проблемой. Продолжайте прерывистую загрузку, возможно, нет. Думаю, Ctrl-C можно было бы обработать. Работала над Windows, установила обработчик для индикаторов выполнения. Всего 2 экрана кода, 2 экрана для генерации URL-адресов для извлечения.
Ответ 10
Это кажется довольно гибким:
http://keramida.wordpress.com/2010/01/19/parallel-downloads-with-python-and-gnu-wget/