'더 똑똑한'방식으로 파이썬을 사용하여 파일을 다운로드하는 방법은 무엇입니까?
Python에서 http를 통해 여러 파일을 다운로드해야합니다.
가장 확실한 방법은 urllib2를 사용하는 것입니다.
import urllib2
u = urllib2.urlopen('http://server.com/file.html')
localFile = open('file.html', 'w')
localFile.write(u.read())
localFile.close()
그러나 다음과 같이 어떤 식 으로든 불쾌한 URL을 처리해야합니다 http://server.com/!Run.aspx/someoddtext/somemore?id=121&m=pdf.. 브라우저를 통해 다운로드 할 때 파일 이름은 사람이 읽을 수 있습니다. accounts.pdf.
파이썬에서 처리 할 수있는 방법이 있습니까? 그래서 파일 이름을 알 필요가없고 스크립트에 하드 코딩 할 필요가 없습니까?
이와 같은 다운로드 스크립트는 사용자 에이전트에게 파일 이름을 지정하는 헤더를 푸시하는 경향이 있습니다.
Content-Disposition: attachment; filename="the filename.ext"
해당 헤더를 잡을 수 있다면 적절한 파일 이름을 얻을 수 있습니다.
거기에 다른 스레드 를 위해 제공하는 코드의 약간을 가지고 Content-Disposition-grabbing은.
remotefile = urllib2.urlopen('http://example.com/somefile.zip')
remotefile.info()['Content-Disposition']
댓글과 @Oli의 anwser를 기반으로 다음과 같은 솔루션을 만들었습니다.
from os.path import basename
from urlparse import urlsplit
def url2name(url):
return basename(urlsplit(url)[2])
def download(url, localFileName = None):
localName = url2name(url)
req = urllib2.Request(url)
r = urllib2.urlopen(req)
if r.info().has_key('Content-Disposition'):
# If the response has Content-Disposition, we take file name from it
localName = r.info()['Content-Disposition'].split('filename=')[1]
if localName[0] == '"' or localName[0] == "'":
localName = localName[1:-1]
elif r.url != url:
# if we were redirected, the real file name we take from the final URL
localName = url2name(r.url)
if localFileName:
# we can force to save the file as specified name
localName = localFileName
f = open(localName, 'wb')
f.write(r.read())
f.close()
It takes file name from Content-Disposition; if it's not present, uses filename from the URL (if redirection happened, the final URL is taken into account).
Combining much of the above, here is a more pythonic solution:
import urllib2
import shutil
import urlparse
import os
def download(url, fileName=None):
def getFileName(url,openUrl):
if 'Content-Disposition' in openUrl.info():
# If the response has Content-Disposition, try to get filename from it
cd = dict(map(
lambda x: x.strip().split('=') if '=' in x else (x.strip(),''),
openUrl.info()['Content-Disposition'].split(';')))
if 'filename' in cd:
filename = cd['filename'].strip("\"'")
if filename: return filename
# if no filename was found above, parse it out of the final URL.
return os.path.basename(urlparse.urlsplit(openUrl.url)[2])
r = urllib2.urlopen(urllib2.Request(url))
try:
fileName = fileName or getFileName(url,r)
with open(fileName, 'wb') as f:
shutil.copyfileobj(r,f)
finally:
r.close()
2 Kender:
if localName[0] == '"' or localName[0] == "'":
localName = localName[1:-1]
it is not safe -- web server can pass wrong formatted name as ["file.ext] or [file.ext'] or even be empty and localName[0] will raise exception. Correct code can looks like this:
localName = localName.replace('"', '').replace("'", "")
if localName == '':
localName = SOME_DEFAULT_FILE_NAME
Using wget:
custom_file_name = "/custom/path/custom_name.ext"
wget.download(url, custom_file_name)
Using urlretrieve:
urllib.urlretrieve(url, custom_file_name)
urlretrieve also creates the directory structure if not exists.
참고URL : https://stackoverflow.com/questions/862173/how-to-download-a-file-using-python-in-a-smarter-way
'Program Club' 카테고리의 다른 글
| 조각을 사용하는 이유는 무엇입니까? (0) | 2020.11.11 |
|---|---|
| C ++에서 생성자와 소멸자가 인라인 함수가 될 수 있습니까? (0) | 2020.11.11 |
| 요소의 계산 된 스타일을 반환하여 해당 요소를 의사 복제하는 jQuery CSS 플러그인? (0) | 2020.11.11 |
| 전화 통화를위한 URL 체계 (0) | 2020.11.11 |
| 포함 파일이 저장된 위치-Ubuntu Linux, GCC (0) | 2020.11.11 |