Comment enregistrer une image localement en utilisant Python dont je connais déjà l'adresse URL?

Réponses:

316

Python 2

Voici un moyen plus simple si tout ce que vous voulez faire est de l'enregistrer sous forme de fichier:

import urllib

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

Le deuxième argument est le chemin local où le fichier doit être enregistré.

Python 3

Comme SergO l'a suggéré, le code ci-dessous devrait fonctionner avec Python 3.

import urllib.request

urllib.request.urlretrieve("http://www.digimouth.com/news/media/2011/09/google-logo.jpg", "local-filename.jpg")
Liquid_Fire
la source
55
Un bon moyen d'obtenir le nom de fichier à partir du lien estfilename = link.split('/')[-1]
heltonbiker
2
avec urlretrieve, je reçois juste un fichier de 1 Ko avec un dict et un texte d'erreur 404 à l'intérieur. Si j'entre l'URL dans mon navigateur, je peux obtenir l'image
Yebach
2
@Yebach: Le site à partir duquel vous téléchargez peut utiliser des cookies, le User-Agent ou d'autres en-têtes pour déterminer quel contenu vous servir. Ceux-ci seront différents entre votre navigateur et Python.
Liquid_Fire
27
Python 3 : import urllib.request eturllib.request.urlretrieve(), en conséquence.
SergO
1
@SergO - pouvez-vous ajouter la partie Python 3 à la réponse d'origine?
Sreejith Menon
27
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 contiendra votre image.

Noufal Ibrahim
la source
2
Vous devez ouvrir le fichier en mode binaire: open("file01.jpg", "wb")sinon vous risquez de corrompre l'image.
Liquid_Fire
2
urllib.urlretrievepeut enregistrer l'image directement.
heltonbiker
17

J'ai écrit un script qui fait exactement cela , et il est disponible sur mon github pour votre utilisation.

J'ai utilisé BeautifulSoup pour me permettre d'analyser n'importe quel site Web à la recherche d'images. Si vous allez faire beaucoup de web scraping (ou avez l'intention d'utiliser mon outil), je vous suggère sudo pip install BeautifulSoup. Des informations sur BeautifulSoup sont disponibles ici .

Pour plus de commodité, voici mon 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')
Ouaip.
la source
11

Cela peut être fait avec des demandes. Chargez la page et videz le contenu binaire dans un fichier.

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)
AlexG
la source
1
en-têtes des utilisateurs dans les demandes en cas de mauvaise demande :)
1UC1F3R616
6

Une solution qui fonctionne avec Python 2 et 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")

ou, si l'exigence supplémentaire de requestsest acceptable et s'il s'agit d'une URL http (s):

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)
Martin Thoma
la source
5

J'ai fait un script qui étend le script de Yup. J'ai réparé certaines choses. Il contournera désormais 403: Problèmes interdits. Il ne plantera pas lorsqu'une image ne sera pas récupérée. Il essaie d'éviter les aperçus corrompus. Il obtient les bonnes URL absolues. Il donne plus d'informations. Il peut être exécuté avec un argument depuis la ligne de commande.

# 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)
madprops
la source
3

Utilisation de la bibliothèque de requêtes

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)
Sohan Das
la source
Il semble que l'en-tête est vraiment important dans mon cas, j'obtenais des erreurs 403. Ça a marché.
Ishtiyaq Husain
2

C'est une réponse très courte.

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

Version pour Python 3

J'ai ajusté le code de @madprops pour 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')
Giovanni G. PY
la source
1

Quelque chose de frais pour Python 3 utilisant les requêtes:

Commentaires dans le code. Fonction prête à l'emploi.


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")
Pavel Pančocha
la source
0

Réponse tardive, mais pour python>=3.6vous pouvez utiliser dload , c'est-à-dire:

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

si vous avez besoin de l'image comme bytes, utilisez:

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

installer en utilisant pip3 install dload

CONvid19
la source
-2
img_data=requests.get('https://apod.nasa.gov/apod/image/1701/potw1636aN159_HST_2048.jpg')

with open(str('file_name.jpg', 'wb') as handler:
    handler.write(img_data)
Lewis Mann
la source
4
Bienvenue dans Stack Overflow! Bien que vous ayez peut-être résolu le problème de cet utilisateur, les réponses de code uniquement ne sont pas très utiles pour les utilisateurs qui viendront à cette question à l'avenir. Veuillez modifier votre réponse pour expliquer pourquoi votre code résout le problème d'origine.
Joe C
1
TypeError: a bytes-like object is required, not 'Response'. Ça doit êtrehandler.write(img_data.content)
TitanFighter
Ça devrait être handler.write(img_data.read()).
jdhao