Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to download image using requests

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?

like image 305
shkschneider Avatar asked Oct 30 '12 11:10

shkschneider


2 Answers

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.

like image 112
Martijn Pieters Avatar answered Sep 28 '22 06:09

Martijn Pieters


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 
like image 33
Oleh Prypin Avatar answered Sep 28 '22 07:09

Oleh Prypin