I'm trying to download and save an image from the web using python's requests
module.
Here is the (working) code I used:
img = urllib2.urlopen(settings.STATICMAP_URL.format(**data)) with open(path, 'w') as f: f.write(img.read())
Here is the new (non-working) code using 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)
Can you help me on what attribute from the response to use from requests
?
You can either use the response.raw
file object, or iterate over the response.
To use the response.raw
file-like object will not, by default, decode compressed responses (with GZIP or deflate). You can force it to decompress for you anyway by setting the decode_content
attribute to True
(requests
sets it to False
to control decoding itself). You can then use shutil.copyfileobj()
to have Python stream the data to a file object:
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)
To iterate over the response use a loop; iterating like this ensures that data is decompressed by this stage:
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)
This'll read the data in 128 byte chunks; if you feel another chunk size works better, use the Response.iter_content()
method with a custom chunk size:
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)
Note that you need to open the destination file in binary mode to ensure python doesn't try and translate newlines for you. We also set stream=True
so that requests
doesn't download the whole image into memory first.
Get a file-like object from the request and copy it to a file. This will also avoid reading the whole thing into memory at once.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With