У меня есть небольшая утилита, которую я использую для загрузки MP3 с веб-сайта по расписанию, а затем создает/обновляет XML-файл подкаста, который я'очевидно, добавляю в iTunes.
Обработка текста, создающая/обновляющая XML-файл, написана на Python. Я использую wget внутри Windows .bat
файла для загрузки фактического MP3, однако. Я бы предпочел, чтобы вся утилита была написана на Python.
Мне не удалось найти способ загрузить файл на Python, поэтому я прибегнул к wget
.
Итак, как мне загрузить файл с помощью Python?
Еще один, используя 'urlretrieve':
import urllib
urllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
(для Пайтона 3 + использование 'импортируют urllib.request' и 'urllib.request.urlretrieve'),
Еще один, с " progressbar"
import urllib2
url = "http://download.thinkbroadband.com/10MB.zip"
file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)
file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print status,
f.close()
В Python 2 используйте urllib2, который поставляется вместе со стандартной библиотекой.
import urllib2
response = urllib2.urlopen('http://www.example.com/')
html = response.read()
Это самый базовый способ использования библиотеки, без какой-либо обработки ошибок. Вы также можете делать более сложные вещи, например, изменять заголовки. Документацию можно найти здесь.
В 2012 используйте питон просит библиотеку
>>> import requests
>>>
>>> url = "http://download.thinkbroadband.com/10MB.zip"
>>> r = requests.get(url)
>>> print len(r.content)
10485760
Вы можете управлять 'зернышком, устанавливают запросы', чтобы получить его.
У запросов есть много преимуществ перед альтернативами, потому что API намного более прост. Это особенно верно, если Вы должны сделать идентификацию. urllib и urllib2 довольно неинтуитивные и болезненные в этом случае.
2015-12-30
Люди выразили восхищение индикатором выполнения. It' s прохладный, уверенный. Есть несколько стандартных решений теперь, включая 'tqdm':
from tqdm import tqdm
import requests
url = "http://download.thinkbroadband.com/10MB.zip"
response = requests.get(url, stream=True)
with open("10MB", "wb") as handle:
for data in tqdm(response.iter_content()):
handle.write(data)
Это - по существу внедрение @kvance, описал 30 месяцев назад.
import urllib2
mp3file = urllib2.urlopen("http://www.example.com/songs/mp3.mp3")
with open('test.mp3','wb') as output:
output.write(mp3file.read())
wb
в open('test.mp3','wb')
открывает файл (и стирает любой существующий файл) в двоичном режиме, чтобы вы могли сохранять данные с его помощью, а не только текст.
['urllib.request.urlopen'] (https://docs.python.org/3/library/urllib.request.html#urllib.request.urlopen)
импорт urllib.request
ответ = urllib.request.urlopen (' http://www.example.com/')
HTML = response.read ()
['urllib.request.urlretrieve'] (https://docs.python.org/3/library/urllib.request.html#urllib.request.urlretrieve)
импорт urllib.request
urllib.request.urlretrieve (' http://www.example.com/songs/mp3.mp3' ' mp3.mp3')
['urllib2.urlopen'] (https://docs.python.org/2/library/urllib2.html#urllib2.urlopen) (спасибо [Кори] (https://stackoverflow.com/a/22682/399105))
импорт urllib2
ответ = urllib2.urlopen (' http://www.example.com/')
HTML = response.read ()
['urllib.urlretrieve'] (https://docs.python.org/2/library/urllib.html#urllib.urlretrieve) (спасибо [PabloG] (https://stackoverflow.com/a/22776/399105))
импорт urllib
urllib.urlretrieve (' http://www.example.com/songs/mp3.mp3' ' mp3.mp3')
использование wget модуль:
import wget
wget.download('url')
Улучшенная версия PabloG кодирует для Пайтона 2/3:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import ( division, absolute_import, print_function, unicode_literals )
import sys, os, tempfile, logging
if sys.version_info >= (3,):
import urllib.request as urllib2
import urllib.parse as urlparse
else:
import urllib2
import urlparse
def download_file(url, dest=None):
"""
Download and save a file specified by url to dest directory,
"""
u = urllib2.urlopen(url)
scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
filename = os.path.basename(path)
if not filename:
filename = 'downloaded.file'
if dest:
filename = os.path.join(dest, filename)
with open(filename, 'wb') as f:
meta = u.info()
meta_func = meta.getheaders if hasattr(meta, 'getheaders') else meta.get_all
meta_length = meta_func("Content-Length")
file_size = None
if meta_length:
file_size = int(meta_length[0])
print("Downloading: {0} Bytes: {1}".format(url, file_size))
file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break
file_size_dl += len(buffer)
f.write(buffer)
status = "{0:16}".format(file_size_dl)
if file_size:
status += " [{0:6.2f}%]".format(file_size_dl * 100 / file_size)
status += chr(13)
print(status, end="")
print()
return filename
if __name__ == "__main__": # Only run if this file is called directly
print("Testing with 10MB download")
url = "http://download.thinkbroadband.com/10MB.zip"
filename = download_file(url)
print(filename)
Простой все же 'Питон 2 & Питон 3' совместимых пути идет 'шесть' библиотека:
from six.moves import urllib
urllib.request.urlretrieve("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
import os,requests
def download(url):
get_response = requests.get(url,stream=True)
file_name = url.split("/")[-1]
with open(file_name, 'wb') as f:
for chunk in get_response.iter_content(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
download("https://example.com/example.jpg")
Написал библиотеке wget в чистом Пайтоне просто с этой целью. Это качается 'urlretrieve' с [эти особенности] [2] с версии 2.0.
[2]: https://bitbucket.org/techtonik/python-wget/src/6859e7b4aba37cef57616111be890fb59631bc4c/wget.py? at=default#cl-330
Следующее - обычно используемые призывы к загрузке файлов у питона:
'urllib.urlretrieve (' url_to_file' file_name)'
'urllib2.urlopen (' url_to_file')'
'requests.get (URL)'
'wget.download (' url' file_name)'
Примечание: 'urlopen' и 'urlretrieve', как находят, выступают относительно плохо с загрузкой больших файлов (размер > 500 МБ). 'requests.get' хранит файл в памяти, пока загрузка не завершена.
Я согласен с Кори, urllib2 является более полным, чем urllib и, вероятно, должен быть модулем, используемым, если вы хотите делать более сложные вещи, но чтобы сделать ответы более полными, urllib является более простым модулем, если вам нужны только основы:
import urllib
response = urllib.urlopen('http://www.example.com/sound.mp3')
mp3 = response.read()
будет работать отлично. Или, если вы не хотите иметь дело с объектом "response", вы можете вызвать read() напрямую:
import urllib
mp3 = urllib.urlopen('http://www.example.com/sound.mp3').read()
Вы можете получить обратную связь прогресса с urlretrieve также:
def report(blocknr, blocksize, size):
current = blocknr*blocksize
sys.stdout.write("\r{0:.2f}%".format(100.0*current/size))
def downloadFile(url):
print "\n",url
fname = url.split('/')[-1]
print fname
urllib.urlretrieve(url, fname, report)
Если у Вас есть установленный wget, Вы можете использовать parallel_sync.
зернышко устанавливает parallel_sync
from parallel_sync import wget
urls = ['http://something.png', 'http://somthing.tar.gz', 'http://somthing.zip']
wget.download('/tmp', urls)
# or a single file:
wget.download('/tmp', urls[0], filenames='x.zip', extract=True)
Доктор: https://pythonhosted.org/parallel_sync/pages/examples.html
Это довольно сильно. Это может загрузить файлы параллельно, повторить после неудачи, и это может даже загрузить файлы на отдаленной машине.
В python3 Вы можете использовать urllib3 и shutil библиотеки. Загрузите их при помощи зернышка или pip3 (Зависящий, является ли python3 дефолтом или не),
pip3 install urllib3 shutil
Тогда управляйте этим кодексом
import urllib.request
import shutil
url = "http://www.somewebsite.com/something.pdf"
output_file = "save_this_name.pdf"
with urllib.request.urlopen(url) as response, open(output_file, 'wb') as out_file:
shutil.copyfileobj(response, out_file)
Обратите внимание, что Вы загружаете 'urllib3', но используете 'urllib' в кодексе
Только ради полноты, также возможно назвать любую программу для восстановления файлов, используя пакет 'подпроцесса'. Программы, посвященные восстановлению файлов, более сильны, чем функции Пайтона как 'urlretrieve'. Например, ['wget'] (https://www.gnu.org/software/wget/) может загрузить справочники рекурсивно ('-r'), может иметь дело с FTP, перенаправления, полномочия HTTP, могут постараться не повторно загружать существующие файлы ('-nc'), и ['aria2'] (https://aria2.github.io/) может сделать загрузки мультисвязи, которые могут потенциально ускорить Ваши загрузки.
import subprocess
subprocess.check_output(['wget', '-O', 'example_output_file.html', 'https://example.com'])
В Ноутбуке Jupyter можно также назвать программы непосредственно с'!' синтаксис:
!wget -O example_output_file.html https://example.com
Если скорость имеет значение для Вас, я сделал маленькие промышленные испытания для модулей 'urllib' и 'wget', и относительно 'wget' я попробовал однажды статусной строкой и однажды без. Я взял три различных файла 500 МБ, чтобы проверить с (различные файлы - чтобы устранить шанс, что есть некоторое кэширование, продолжающееся под капотом). Проверенный на debian машине, с python2.
Во-первых, это результаты (они подобны в различных пробегах):
$ python wget_test.py
urlretrive_test : starting
urlretrive_test : 6.56
==============
wget_no_bar_test : starting
wget_no_bar_test : 7.20
==============
wget_with_bar_test : starting
100% [......................................................................] 541335552 / 541335552
wget_with_bar_test : 50.49
==============
Путем я выступил, тест использует " profile" декоратор. Это - полный кодекс:
import wget
import urllib
import time
from functools import wraps
def profile(func):
@wraps(func)
def inner(*args):
print func.__name__, ": starting"
start = time.time()
ret = func(*args)
end = time.time()
print func.__name__, ": {:.2f}".format(end - start)
return ret
return inner
url1 = 'http://host.com/500a.iso'
url2 = 'http://host.com/500b.iso'
url3 = 'http://host.com/500c.iso'
def do_nothing(*args):
pass
@profile
def urlretrive_test(url):
return urllib.urlretrieve(url)
@profile
def wget_no_bar_test(url):
return wget.download(url, out='/tmp/', bar=do_nothing)
@profile
def wget_with_bar_test(url):
return wget.download(url, out='/tmp/')
urlretrive_test(url1)
print '=============='
time.sleep(1)
wget_no_bar_test(url2)
print '=============='
time.sleep(1)
wget_with_bar_test(url3)
print '=============='
time.sleep(1)
'urllib', кажется, является самым быстрым
Вы можете использовать PycURL на Пайтоне 2 и 3.
import pycurl
FILE_DEST = 'pycurl.html'
FILE_SRC = 'http://pycurl.io/'
with open(FILE_DEST, 'wb') as f:
c = pycurl.Curl()
c.setopt(c.URL, FILE_SRC)
c.setopt(c.WRITEDATA, f)
c.perform()
c.close()
Я написал следующее, которое работает в ванили Пайтон 2 или Пайтон 3.
import sys
try:
import urllib.request
python3 = True
except ImportError:
import urllib2
python3 = False
def progress_callback_simple(downloaded,total):
sys.stdout.write(
"\r" +
(len(str(total))-len(str(downloaded)))*" " + str(downloaded) + "/%d"%total +
" [%3.2f%%]"%(100.0*float(downloaded)/float(total))
)
sys.stdout.flush()
def download(srcurl, dstfilepath, progress_callback=None, block_size=8192):
def _download_helper(response, out_file, file_size):
if progress_callback!=None: progress_callback(0,file_size)
if block_size == None:
buffer = response.read()
out_file.write(buffer)
if progress_callback!=None: progress_callback(file_size,file_size)
else:
file_size_dl = 0
while True:
buffer = response.read(block_size)
if not buffer: break
file_size_dl += len(buffer)
out_file.write(buffer)
if progress_callback!=None: progress_callback(file_size_dl,file_size)
with open(dstfilepath,"wb") as out_file:
if python3:
with urllib.request.urlopen(srcurl) as response:
file_size = int(response.getheader("Content-Length"))
_download_helper(response,out_file,file_size)
else:
response = urllib2.urlopen(srcurl)
meta = response.info()
file_size = int(meta.getheaders("Content-Length")[0])
_download_helper(response,out_file,file_size)
import traceback
try:
download(
"https://geometrian.com/data/programming/projects/glLib/glLib%20Reloaded%200.5.9/0.5.9.zip",
"output.zip",
progress_callback_simple
)
except:
traceback.print_exc()
input()
Примечания: