Я пытаюсь получить файл 500 МБ с помощью Python, и у меня есть сценарий, который использует urllib.urlretrieve()
. Там кажется некоторой сетевой проблеме между мной и сайтом для скачивания, поскольку этот вызов последовательно зависает и не удается завершиться. Однако использование wget
получать файл имеет тенденцию работать без проблем. Между чем различие urlretrieve()
и wget
это могло вызвать это различие?
Ответ довольно прост. Python urllib
и urllib2
далеко не такие зрелые и надежные, как могли бы быть. По моему опыту, даже лучше, чем wget, - cURL
. Я написал код, который загружает гигабайты файлов через HTTP с размерами файлов от 50 КБ до более 2 ГБ. Насколько мне известно, cURL является наиболее надежным программным обеспечением на планете на данный момент для решения этой задачи. Я не думаю, что python, wget или даже большинство веб-браузеров могут ему соответствовать с точки зрения правильности и надежности реализации. На достаточно современном питоне, использующем urllib2 правильным образом, его можно сделать довольно надежным, но я все еще запускаю подпроцесс curl, и это абсолютно надежно.
Другой способ заявить об этом заключается в том, что cURL делает только одно, и делает это лучше, чем любое другое программное обеспечение, потому что оно подверглось гораздо большему развитию и усовершенствованию. Python urllib2
удобен в обслуживании и достаточно хорошо работает для небольших и средних рабочих нагрузок, но cURL намного впереди с точки зрения надежности.
Кроме того, cURL имеет множество опций для настройки поведения надежности, включая количество повторов, значения тайм-аута и т. Д.
Если вы используете:
page = urllib.retrieve('http://example.com/really_big_file.html')
вы создаете строку размером 500 мб, что вполне может нагрузить вашу машину, сделать ее медленной и вызвать таймаут соединения. Если это так, то вам следует использовать:
(filename, headers) = urllib.retrieve('http://...', 'local_outputfile.html')
что не будет нагружать интерпретатор.
Стоит отметить, что urllib.retrieve() использует urllib.urlopen(), который сейчас устарел.