0

I find urllib has a handy way to get image from url:

urllib.urlretrieve( url, localName )

However the requests way seems to be a little tricky. Even the answer suggested urllib to do the job.

Is it correct that requests really can't do the thing just like urllib does? Or, is there a requests interface similar to urllib.urlretrieve()?

My project currently using only requests. I don't want to import another tool for only one feature.

Community
  • 1
  • 1
kaltu
  • 330
  • 5
  • 17

4 Answers4

1

Note that urllib.urlretrieve() is useless with modern unreliable services. If the server answers with status code 500 (Internal Server Error), you have no ways to detect it: the function just writes down the server's answer (empty one or "500 Internal Server Error" or whatever).

With requests you have ability to check the status code.

y0prst
  • 611
  • 1
  • 6
  • 13
0

Just save the response content of a response to a binary file, e.g.:

In [1]: import requests
In [2]: r = requests.get('https://lh3.googleusercontent.com/-NwXieow8Dac/VfWsN9Gnc4I/AAAAAAAATB8/dbaO0RKfIhE/w426-h538/PP_%2B1944wm.jpg')
In [3]: with open('fred.jpg', 'wb') as outfile:
   ...:     outfile.write(r.content)
In [4]: exit()

Saves the image just fine.

Steve Barnes
  • 27,618
  • 6
  • 63
  • 73
0

You can always make a GET request, read the response and then save it to a file.

f=open("filename.jpeg","w")
data=requests.get("http://example.com/img.jpeg");
f.write(data.content)
f.close()
ForceBru
  • 43,482
  • 10
  • 63
  • 98
0

The requests way you are referring to, is solution which is suitable also for large files. As it was already pointed, small files, you can always download via requst.get:

import requests
with open("destination.jpg", "wb") as dst_file:
    dst_file.write(request.get("http://example.com/img.jpeg").content)

If you want solution that's suitable for large files using requests, it's not tricky at all.

Actually when you take a look at urllib.retrieve code, you'll see that's under the hood it's doing basically the same operations as you would need to do for requests.get with stream=True, except (as pointed in @y0prst answer) it's not checking response status code, so it'll write into local file also content of error responses (HTTP 500 code).

You can define function like:

def requests_retrieve(url, filename, chunk_size=1024):
    with open(filename, "wb") as dst_file:
        resp = request.get(url, stream=True)
        resp.raise_for_status()
        for chunk in resp.iter_content(chunk_size)
            dst_file.write(chunk)

And call it like urllib.urlretrieve

request_retrieve(url, localName)
Community
  • 1
  • 1
beezz
  • 2,398
  • 19
  • 15