파이썬 requests
모듈을 사용하여 웹에서 이미지를 다운로드하여 저장하려고 합니다.
내가 사용한 (작동) 코드는 다음과 같습니다.
img = urllib2.urlopen(settings.STATICMAP_URL.format(**data))
with open(path, 'w') as f:
f.write(img.read())
다음은 사용하는 새로운 (작동하지 않는) 코드입니다 requests
.
r = requests.get(settings.STATICMAP_URL.format(**data))
if r.status_code == 200:
img = r.raw.read()
with open(path, 'w') as f:
f.write(img)
응답에서 어떤 속성을 사용할 수 있는지 알려 주 requests
시겠습니까?
답변
response.raw
파일 객체 를 사용하거나 응답을 반복 할 수 있습니다 .
response.raw
파일과 같은 객체 를 사용하는 것은 기본적으로 압축 된 응답 (GZIP 또는 deflate)을 디코딩하지 않습니다. decode_content
어트리뷰트를 True
(로 requests
설정하여 False
디코딩 자체를 제어 하도록 설정하여) 어쨌든 압축을 풀도록 할 수 있습니다 . 그런 다음 shutil.copyfileobj()
파이썬이 데이터를 파일 객체로 스트리밍 하도록 할 수 있습니다 :
import requests
import shutil
r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
with open(path, 'wb') as f:
r.raw.decode_content = True
shutil.copyfileobj(r.raw, f)
응답을 반복하려면 루프를 사용하십시오. 이와 같이 반복하면 데이터가이 단계에서 압축 해제됩니다.
r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
with open(path, 'wb') as f:
for chunk in r:
f.write(chunk)
128 바이트 단위로 데이터를 읽습니다. 다른 청크 크기가 더 잘 작동한다고 생각되면 사용자 지정 청크 크기와 함께이 Response.iter_content()
방법 을 사용하십시오 .
r = requests.get(settings.STATICMAP_URL.format(**data), stream=True)
if r.status_code == 200:
with open(path, 'wb') as f:
for chunk in r.iter_content(1024):
f.write(chunk)
파이썬이 줄 바꿈을 시도하고 변환하지 않도록 대상 파일을 이진 모드로 열어야합니다. 우리는 또한 설정 stream=True
이 그래서 requests
먼저 메모리에 전체 이미지를 다운로드하지 않습니다.
답변
요청에서 파일과 같은 객체를 가져 와서 파일로 복사합니다. 이것은 또한 모든 것을 한 번에 메모리로 읽는 것을 피할 것입니다.
import shutil
import requests
url = 'http://example.com/img.png'
response = requests.get(url, stream=True)
with open('img.png', 'wb') as out_file:
shutil.copyfileobj(response.raw, out_file)
del response
답변
빠른 해결책 인 이건 어떻습니까?
import requests
url = "http://craphound.com/images/1006884_2adf8fc7.jpg"
response = requests.get(url)
if response.status_code == 200:
with open("/Users/apple/Desktop/sample.jpg", 'wb') as f:
f.write(response.content)
답변
요청을 사용하여 이미지를 다운로드해야 할 필요가 동일합니다. 나는 먼저 Martijn Pieters의 답변을 시도했지만 잘 작동합니다. 그러나이 간단한 함수에 대한 프로파일을 만들 때 urllib 및 urllib2에 비해 너무 많은 함수 호출을 사용한다는 것을 알았습니다.
그런 다음 요청 작성자 모듈이 권장 하는 방식 을 시도했습니다 .
import requests
from PIL import Image
# python2.x, use this instead
# from StringIO import StringIO
# for python3.x,
from io import StringIO
r = requests.get('https://example.com/image.jpg')
i = Image.open(StringIO(r.content))
이로 인해 함수 호출 수가 훨씬 줄어들어 애플리케이션 속도가 빨라졌습니다. 내 프로파일 러 코드와 결과는 다음과 같습니다.
#!/usr/bin/python
import requests
from StringIO import StringIO
from PIL import Image
import profile
def testRequest():
image_name = 'test1.jpg'
url = 'http://example.com/image.jpg'
r = requests.get(url, stream=True)
with open(image_name, 'wb') as f:
for chunk in r.iter_content():
f.write(chunk)
def testRequest2():
image_name = 'test2.jpg'
url = 'http://example.com/image.jpg'
r = requests.get(url)
i = Image.open(StringIO(r.content))
i.save(image_name)
if __name__ == '__main__':
profile.run('testUrllib()')
profile.run('testUrllib2()')
profile.run('testRequest()')
testRequest의 결과 :
343080 function calls (343068 primitive calls) in 2.580 seconds
그리고 testRequest2의 결과 :
3129 function calls (3105 primitive calls) in 0.024 seconds
답변
사용하는 것보다 쉽습니다 requests
. 이것은 requests
HTTP 작업을 사용 하지 않는 것이 좋습니다 .
사용하는 두 개의 라이너 urllib
:
>>> import urllib
>>> urllib.request.urlretrieve("http://www.example.com/songs/mp3.mp3", "mp3.mp3")
wget
꽤 사용하기 쉬운 멋진 파이썬 모듈도 있습니다. 찾을 여기 .
이것은 디자인의 단순성을 보여줍니다.
>>> import wget
>>> url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3'
>>> filename = wget.download(url)
100% [................................................] 3841532 / 3841532>
>> filename
'razorback.mp3'
즐겨.
편집 :out
매개 변수를 추가하여 경로를 지정할 수도 있습니다 .
>>> out_filepath = <output_filepath>
>>> filename = wget.download(url, out=out_filepath)
답변
다음 코드 스 니펫은 파일을 다운로드합니다.
파일은 지정된 URL과 같이 파일 이름으로 저장됩니다.
import requests
url = "http://example.com/image.jpg"
filename = url.split("/")[-1]
r = requests.get(url, timeout=0.5)
if r.status_code == 200:
with open(filename, 'wb') as f:
f.write(r.content)
답변
두 가지 주요 방법이 있습니다.
-
.content
(가장 단순한 / 공식적인) 사용 ( Zhenyi Zhang의 답변 참조 ) :import io # Note: io.BytesIO is StringIO.StringIO on Python2. import requests r = requests.get('http://lorempixel.com/400/200') r.raise_for_status() with io.BytesIO(r.content) as f: with Image.open(f) as img: img.show()
-
사용
.raw
( Martijn Pieters의 답변 참조 ) :import requests r = requests.get('http://lorempixel.com/400/200', stream=True) r.raise_for_status() r.raw.decode_content = True # Required to decompress gzip/deflate compressed responses. with PIL.Image.open(r.raw) as img: img.show() r.close() # Safety when stream=True ensure the connection is released.
두 타이밍 모두 눈에 띄는 차이가 없습니다.