210

I know the URL of an image on Internet.

e.g. http://www.digimouth.com/news/media/2011/09/google-logo.jpg, which contains the logo of Google.

Now, how can I download this image using Python without actually opening the URL in a browser and saving the file manually.

1

18 Answers 18

411

Python 2

Here is a more straightforward way if all you want to do is save it as a file:

import urllib urllib.urlretrieve("http://www.digimouth.com/news/media/2011/09/google-logo.jpg", "local-filename.jpg") 

The second argument is the local path where the file should be saved.

Python 3

As SergO suggested the code below should work with Python 3.

import urllib.request urllib.request.urlretrieve("http://www.digimouth.com/news/media/2011/09/google-logo.jpg", "local-filename.jpg") 
Sign up to request clarification or add additional context in comments.

10 Comments

A good way to get filename from link is filename = link.split('/')[-1]
with urlretrieve I just get a 1KB file with a dict and 404 error text inside.Why? If I enter url into my browser I can get the picture
@Yebach: The site you are downloading from may be using cookies, the User-Agent or other headers to determine what content to serve you. These will be different between your browser and Python.
Python 3: import urllib.request and urllib.request.urlretrieve(), accordingly.
How can I know if the the download has succeeded?
|
29
import urllib resource = urllib.urlopen("http://www.digimouth.com/news/media/2011/09/google-logo.jpg") output = open("file01.jpg","wb") output.write(resource.read()) output.close() 

file01.jpg will contain your image.

3 Comments

You should open the file in binary mode: open("file01.jpg", "wb") Otherwise you may corrupt the image.
urllib.urlretrieve can save the image directly.
This was Python 2. Perhaps you have a newer version of Python?
21

I wrote a script that does just this, and it is available on my github for your use.

I utilized BeautifulSoup to allow me to parse any website for images. If you will be doing much web scraping (or intend to use my tool) I suggest you sudo pip install BeautifulSoup. Information on BeautifulSoup is available here.

For convenience here is my code:

from bs4 import BeautifulSoup from urllib2 import urlopen import urllib # use this image scraper from the location that #you want to save scraped images to def make_soup(url): html = urlopen(url).read() return BeautifulSoup(html) def get_images(url): soup = make_soup(url) #this makes a list of bs4 element tags images = [img for img in soup.findAll('img')] print (str(len(images)) + "images found.") print 'Downloading images to current working directory.' #compile our unicode list of image links image_links = [each.get('src') for each in images] for each in image_links: filename=each.split('/')[-1] urllib.urlretrieve(each, filename) return image_links #a standard call looks like this #get_images('http://www.wookmark.com') 

Comments

19

This can be done with requests. Load the page and dump the binary content to a file.

import os import requests url = 'https://apod.nasa.gov/apod/image/1701/potw1636aN159_HST_2048.jpg' page = requests.get(url) f_ext = os.path.splitext(url)[-1] f_name = 'img{}'.format(f_ext) with open(f_name, 'wb') as f: f.write(page.content) 

2 Comments

user headers in requests if getting bad request :)
Also, you likely want to check that page.status_code == 200 before writing the file.
12

Python 3

urllib.request — Extensible library for opening URLs

from urllib.error import HTTPError from urllib.request import urlretrieve try: urlretrieve(image_url, image_local_path) except FileNotFoundError as err: print(err) # something wrong with local path except HTTPError as err: print(err) # something wrong with url 

Comments

7

I made a script expanding on Yup.'s script. I fixed some things. It will now bypass 403:Forbidden problems. It wont crash when an image fails to be retrieved. It tries to avoid corrupted previews. It gets the right absolute urls. It gives out more information. It can be run with an argument from the command line.

# getem.py # python2 script to download all images in a given url # use: python getem.py http://url.where.images.are from bs4 import BeautifulSoup import urllib2 import shutil import requests from urlparse import urljoin import sys import time def make_soup(url): req = urllib2.Request(url, headers={'User-Agent' : "Magic Browser"}) html = urllib2.urlopen(req) return BeautifulSoup(html, 'html.parser') def get_images(url): soup = make_soup(url) images = [img for img in soup.findAll('img')] print (str(len(images)) + " images found.") print 'Downloading images to current working directory.' image_links = [each.get('src') for each in images] for each in image_links: try: filename = each.strip().split('/')[-1].strip() src = urljoin(url, each) print 'Getting: ' + filename response = requests.get(src, stream=True) # delay to avoid corrupted previews time.sleep(1) with open(filename, 'wb') as out_file: shutil.copyfileobj(response.raw, out_file) except: print ' An error occured. Continuing.' print 'Done.' if __name__ == '__main__': url = sys.argv[1] get_images(url) 

Comments

6

A solution which works with Python 2 and Python 3:

try: from urllib.request import urlretrieve # Python 3 except ImportError: from urllib import urlretrieve # Python 2 url = "http://www.digimouth.com/news/media/2011/09/google-logo.jpg" urlretrieve(url, "local-filename.jpg") 

or, if the additional requirement of requests is acceptable and if it is a http(s) URL:

def load_requests(source_url, sink_path): """ Load a file from an URL (e.g. http). Parameters ---------- source_url : str Where to load the file from. sink_path : str Where the loaded file is stored. """ import requests r = requests.get(source_url, stream=True) if r.status_code == 200: with open(sink_path, 'wb') as f: for chunk in r: f.write(chunk) 

Comments

6

Using requests library

import requests import shutil,os headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36' } currentDir = os.getcwd() path = os.path.join(currentDir,'Images')#saving images to Images folder def ImageDl(url): attempts = 0 while attempts < 5:#retry 5 times try: filename = url.split('/')[-1] r = requests.get(url,headers=headers,stream=True,timeout=5) if r.status_code == 200: with open(os.path.join(path,filename),'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw,f) print(filename) break except Exception as e: attempts+=1 print(e) ImageDl(url) 

1 Comment

It seems the header is really important in my case, I was getting 403 errors. It worked.
6

Use a simple python wget module to download the link. Usage below:

import wget wget.download('http://www.digimouth.com/news/media/2011/09/google-logo.jpg') 

Comments

3

This is very short answer.

import urllib urllib.urlretrieve("http://photogallery.sandesh.com/Picture.aspx?AlubumId=422040", "Abc.jpg") 

Comments

3

Late answer, but for python>=3.6 you can use dload, i.e.:

import dload dload.save("http://www.digimouth.com/news/media/2011/09/google-logo.jpg") 

if you need the image as bytes, use:

img_bytes = dload.bytes("http://www.digimouth.com/news/media/2011/09/google-logo.jpg") 

install using pip3 install dload

Comments

2

Version for Python 3

I adjusted the code of @madprops for Python 3

# getem.py # python2 script to download all images in a given url # use: python getem.py http://url.where.images.are from bs4 import BeautifulSoup import urllib.request import shutil import requests from urllib.parse import urljoin import sys import time def make_soup(url): req = urllib.request.Request(url, headers={'User-Agent' : "Magic Browser"}) html = urllib.request.urlopen(req) return BeautifulSoup(html, 'html.parser') def get_images(url): soup = make_soup(url) images = [img for img in soup.findAll('img')] print (str(len(images)) + " images found.") print('Downloading images to current working directory.') image_links = [each.get('src') for each in images] for each in image_links: try: filename = each.strip().split('/')[-1].strip() src = urljoin(url, each) print('Getting: ' + filename) response = requests.get(src, stream=True) # delay to avoid corrupted previews time.sleep(1) with open(filename, 'wb') as out_file: shutil.copyfileobj(response.raw, out_file) except: print(' An error occured. Continuing.') print('Done.') if __name__ == '__main__': get_images('http://www.wookmark.com') 

Comments

2

Something fresh for Python 3 using Requests:

Comments in the code. Ready to use function.

 import requests from os import path def get_image(image_url): """ Get image based on url. :return: Image name if everything OK, False otherwise """ image_name = path.split(image_url)[1] try: image = requests.get(image_url) except OSError: # Little too wide, but work OK, no additional imports needed. Catch all conection problems return False if image.status_code == 200: # we could have retrieved error page base_dir = path.join(path.dirname(path.realpath(__file__)), "images") # Use your own path or "" to use current working directory. Folder must exist. with open(path.join(base_dir, image_name), "wb") as f: f.write(image.content) return image_name get_image("https://apod.nasddfda.gov/apod/image/2003/S106_Mishra_1947.jpg") 

Comments

2

this is the easiest method to download images.

import requests from slugify import slugify img_url = 'https://apod.nasa.gov/apod/image/1701/potw1636aN159_HST_2048.jpg' img = requests.get(img_url).content img_file = open(slugify(img_url) + '.' + str(img_url).split('.')[-1], 'wb') img_file.write(img) img_file.close() 

Comments

1

If you don't already have the url for the image, you could scrape it with gazpacho:

from gazpacho import Soup base_url = "http://books.toscrape.com" soup = Soup.get(base_url) links = [img.attrs["src"] for img in soup.find("img")] 

And then download the asset with urllib as mentioned:

from pathlib import Path from urllib.request import urlretrieve as download directory = "images" Path(directory).mkdir(exist_ok=True) link = links[0] name = link.split("/")[-1] download(f"{base_url}/{link}", f"{directory}/{name}") 

Comments

0
# import the required libraries from Python import pathlib,urllib.request # Using pathlib, specify where the image is to be saved downloads_path = str(pathlib.Path.home() / "Downloads") # Form a full image path by joining the path to the # images' new name picture_path = os.path.join(downloads_path, "new-image.png") # "/home/User/Downloads/new-image.png" # Using "urlretrieve()" from urllib.request save the image urllib.request.urlretrieve("//example.com/image.png", picture_path) # urlretrieve() takes in 2 arguments # 1. The URL of the image to be downloaded # 2. The image new name after download. By default, the image is saved # inside your current working directory 

Comments

-1

Download Image file, with avoiding all possible error:

import requests import validators from urllib.request import Request, urlopen from urllib.error import URLError, HTTPError def is_downloadable(url): valid=validators. url(url) if valid==False: return False req = Request(url) try: response = urlopen(req) except HTTPError as e: return False except URLError as e: return False else: return True for i in range(len(File_data)): #File data Contain list of address for image #file url = File_data[i][1] try: if (is_downloadable(url)): try: r = requests.get(url, allow_redirects=True) if url.find('/'): fname = url.rsplit('/', 1)[1] fname = pth+File_data[i][0]+"$"+fname #Destination to save #image file open(fname, 'wb').write(r.content) except Exception as e: print(e) except Exception as e: print(e) 

1 Comment

Fun fact: the status can change between calling the downloadable function and actually downloading the file, making this exercise somewhat pointless
-1

Ok, so, this is my rudimentary attempt, and probably total overkill. Update if needed, as this doesn't handle any timeouts, but, I got this working for fun.

Code listed here: https://github.com/JayRizzo/JayRizzoTools/blob/master/pyImageDownloader.py

#!/usr/bin/env python3 # -*- coding: utf-8 -*- # ============================================================================= # Created Syst: MAC OSX High Sierra 21.5.0 (17G65) # Created Plat: Python 3.9.5 ('v3.9.5:0a7dcbdb13', 'May 3 2021 13:17:02') # Created By : Jeromie Kirchoff # Created Date: Thu Jun 15 23:31:01 2022 CDT # Last ModDate: Thu Jun 16 01:41:01 2022 CDT # ============================================================================= # NOTE: Doesn't work on SVG images at this time. # I will look into this further: https://stackoverflow.com/a/6599172/1896134 # ============================================================================= import requests # to get image from the web import shutil # to save it locally import os # needed from os.path import exists as filepathexist # check if file paths exist from os.path import join # joins path for different os from os.path import expanduser # expands current home from pyuser_agent import UA # generates random UserAgent class ImageDownloader(object): """URL ImageDownloader. Input : Full Image URL Output: Image saved to your ~/Pictures/JayRizzoDL folder. """ def __init__(self, URL: str): self.url = URL self.headers = {"User-Agent" : UA().random} self.currentHome = expanduser('~') self.desktop = join(self.currentHome + "/Desktop/") self.download = join(self.currentHome + "/Downloads/") self.pictures = join(self.currentHome + "/Pictures/JayRizzoDL/") self.outfile = "" self.filename = "" self.response = "" self.rawstream = "" self.createdfilepath = "" self.imgFileName = "" # Check if the JayRizzoDL exists in the pictures folder. # if it doesn't exist create it. if not filepathexist(self.pictures): os.mkdir(self.pictures) self.main() def getFileNameFromURL(self, URL: str): """Parse the URL for the name after the last forward slash.""" NewFileName = self.url.strip().split('/')[-1].strip() return NewFileName def getResponse(self, URL: str): """Try streaming the URL for the raw data.""" self.response = requests.get(self.url, headers=self.headers, stream=True) return self.response def gocreateFile(self, name: str, response): """Try creating the file with the raw data in a custom folder.""" self.outfile = join(self.pictures, name) with open(self.outfile, 'wb') as outFilePath: shutil.copyfileobj(response.raw, outFilePath) return self.outfile def main(self): """Combine Everything and use in for loops.""" self.filename = self.getFileNameFromURL(self.url) self.rawstream = self.getResponse(self.url) self.createdfilepath = self.gocreateFile(self.filename, self.rawstream) print(f"File was created: {self.createdfilepath}") return if __name__ == '__main__': # Example when calling the file directly. ImageDownloader("https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png") 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.