Python을 사용하여 HTTP를 통해 파일을 다운로드하려면 어떻게해야합니까?
일정에 따라 웹 사이트에서 MP3를 다운로드 한 다음 iTunes에 추가 한 팟 캐스트 XML 파일을 빌드 / 업데이트하는 데 사용하는 작은 유틸리티가 있습니다.
XML 파일을 생성 / 업데이트하는 텍스트 처리는 Python으로 작성됩니다. .bat
그러나 Windows 파일 내에서 wget을 사용 하여 실제 MP3를 다운로드합니다. 그래도 전체 유틸리티를 Python으로 작성하고 싶습니다.
나는 실제로 파이썬에서 파일을 다운로드하는 방법을 찾기 위해 고심했고, 그래서 wget
.
그렇다면 Python을 사용하여 파일을 어떻게 다운로드합니까?
Python 2에서는 표준 라이브러리와 함께 제공되는 urllib2를 사용합니다.
import urllib2
response = urllib2.urlopen('http://www.example.com/')
html = response.read()
이것은 오류 처리를 제외한 라이브러리를 사용하는 가장 기본적인 방법입니다. 헤더 변경과 같은 더 복잡한 작업을 수행 할 수도 있습니다. 문서는 여기 에서 찾을 수 있습니다.
하나 더, 사용 urlretrieve
:
import urllib
urllib.urlretrieve ("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
(Python 3 이상 사용 import urllib.request
및 urllib.request.urlretrieve
)
"진행률 표시 줄"이있는 또 다른
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()
2012 년에는 python 요청 라이브러리 사용
>>> import requests
>>>
>>> url = "http://download.thinkbroadband.com/10MB.zip"
>>> r = requests.get(url)
>>> print len(r.content)
10485760
당신은 pip install requests
그것을 얻기 위해 달릴 수 있습니다 .
API가 훨씬 간단하기 때문에 요청은 대안에 비해 많은 이점이 있습니다. 인증을해야하는 경우 특히 그렇습니다. urllib와 urllib2는이 경우 매우 직관적이지 않고 고통 스럽습니다.
2015-12-30
사람들은 진행률 표시 줄에 감탄을 표했습니다. 멋지네요. 현재 다음과 같은 여러 가지 기성 솔루션이 있습니다 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)
이것은 본질적으로 30 개월 전에 설명한 @kvance 구현입니다.
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')
파일을 열고 (기존의 모든 파일을 삭제합니다) 당신은 단지 텍스트 대신 그것으로 데이터를 저장할 수 있도록 바이너리 모드로.
파이썬 3
-
import urllib.request response = urllib.request.urlopen('http://www.example.com/') html = response.read()
-
import urllib.request urllib.request.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')
파이썬 2
urllib2.urlopen
( Corey에게 감사드립니다 )import urllib2 response = urllib2.urlopen('http://www.example.com/') html = response.read()
urllib.urlretrieve
( PabloG에게 감사 드립니다 )import urllib urllib.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')
wget 모듈 사용 :
import wget
wget.download('url')
Python 2/3 용 PabloG 코드의 개선 된 버전 :
#!/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)
간단하지만 Python 2 & Python 3
호환되는 방법은 six
라이브러리 와 함께 제공됩니다 .
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.0으로.
Corey에 동의합니다. 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()
다음은 Python에서 파일을 다운로드하는 데 가장 일반적으로 사용되는 호출입니다.
urllib.urlretrieve ('url_to_file', file_name)
urllib2.urlopen('url_to_file')
requests.get(url)
wget.download('url', file_name)
참고 : urlopen
및 urlretrieve
대용량 파일 (크기> 500MB의) 다운로드 상대적으로 나쁜 수행 발견된다. requests.get
다운로드가 완료 될 때까지 파일을 메모리에 저장합니다.
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를 사용할 수 있습니다.
pip install 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 libraires를 사용할 수 있습니다. pip 또는 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
코드에서 사용하십시오 .
완전성을 위해 subprocess
패키지를 사용하여 파일을 검색하기 위해 모든 프로그램을 호출 할 수도 있습니다 . 파일 검색 전용 프로그램은 urlretrieve
. 예를 들어, wget
디렉토리를 재귀 적으로 다운로드 할 수 있고 ( -R
), FTP, 리디렉션, HTTP 프록시를 처리 할 수 있고, 기존 파일을 다시 다운로드 하지 않을 수 있으며 ( -nc
), aria2
잠재적으로 다운로드 속도를 높일 수있는 다중 연결 다운로드를 수행 할 수 있습니다.
import subprocess
subprocess.check_output(['wget', '-O', 'example_output_file.html', 'https://example.com'])
Jupyter Notebook에서는 다음 !
구문을 사용하여 프로그램을 직접 호출 할 수도 있습니다 .
!wget -O example_output_file.html https://example.com
당신에게 속도 문제는, 내가 모듈을위한 작은 성능 테스트 한 경우 urllib
와 wget
,와 관련하여 wget
나는 상태 표시 줄에 및없이 일단 한 번 시도했다. 테스트를 위해 500MB 파일 3 개를 사용했습니다 (다른 파일-내부에서 캐싱이 진행될 가능성을 없애기 위해). 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
==============
테스트를 수행 한 방법은 "프로필"데코레이터를 사용하는 것입니다. 다음은 전체 코드입니다.
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
가장 빠른 것 같습니다
소스 코드는 다음과 같습니다.
import urllib
sock = urllib.urlopen("http://diveintopython.org/")
htmlSource = sock.read()
sock.close()
print htmlSource
Python 2 및 3에서 PycURL 을 사용할 수 있습니다 .
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()
메모:
- "진행률 표시 줄"콜백을 지원합니다.
- 내 웹 사이트에서 다운로드 한 4MB 테스트 .zip입니다.
This may be a little late, But I saw pabloG's code and couldn't help adding a os.system('cls') to make it look AWESOME! Check it out :
import urllib2,os
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)
os.system('cls')
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()
If running in an environment other than Windows, you will have to use something other then 'cls'. In MAC OS X and Linux it should be 'clear'.
urlretrieve and requests.get are simple, however the reality not. I have fetched data for couple sites, including text and images, the above two probably solve most of the tasks. but for a more universal solution I suggest the use of urlopen. As it is included in Python 3 standard library, your code could run on any machine that run Python 3 without pre-installing site-package
import urllib.request
url_request = urllib.request.Request(url, headers=headers)
url_connect = urllib.request.urlopen(url_request)
#remember to open file in bytes mode
with open(filename, 'wb') as f:
while True:
buffer = url_connect.read(buffer_size)
if not buffer: break
#an integer value of size of written data
data_wrote = f.write(buffer)
#you could probably use with-open-as manner
url_connect.close()
This answer provides a solution to HTTP 403 Forbidden when downloading file over http using Python. I have tried only requests and urllib modules, the other module may provide something better, but this is the one I used to solve most of the problems.
참고URL : https://stackoverflow.com/questions/22676/how-do-i-download-a-file-over-http-using-python
'programing tip' 카테고리의 다른 글
표준 Python 독 스트링 형식은 무엇입니까? (0) | 2020.09.29 |
---|---|
Git에서 마지막 커밋을 해제하는 방법 (0) | 2020.09.29 |
변수가 함수 유형인지 확인 (0) | 2020.09.29 |
Python 코드가 함수에서 더 빠르게 실행되는 이유는 무엇입니까? (0) | 2020.09.29 |
JSF, Servlet 및 JSP의 차이점은 무엇입니까? (0) | 2020.09.29 |