Wie speichere ich ein Bild lokal mit Python, dessen URL-Adresse ich bereits kenne?

Antworten:

316

Python 2

Hier ist ein einfacher Weg, wenn Sie es nur als Datei speichern möchten:

import urllib

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

Das zweite Argument ist der lokale Pfad, in dem die Datei gespeichert werden soll.

Python 3

Wie SergO vorgeschlagen hat, sollte der folgende Code mit Python 3 funktionieren.

import urllib.request

urllib.request.urlretrieve("http://www.digimouth.com/news/media/2011/09/google-logo.jpg", "local-filename.jpg")
Liquid_Fire
quelle
55
Ein guter Weg, um Dateinamen von Link zu bekommen, istfilename = link.split('/')[-1]
Heltonbiker
2
Mit urlretrieve erhalte ich gerade eine 1-KB-Datei mit einem Diktat und 404-Fehlertext. Warum? Wenn ich URL in meinen Browser
eingebe,
2
@Yebach: Die Website, von der Sie herunterladen, verwendet möglicherweise Cookies, den User-Agent oder andere Header, um zu bestimmen, welche Inhalte für Sie bereitgestellt werden sollen. Diese unterscheiden sich zwischen Ihrem Browser und Python.
Liquid_Fire
27
Python 3 : import urllib.request undurllib.request.urlretrieve()entsprechend.
SergO
1
@SergO - Kannst du den Python 3-Teil zur ursprünglichen Antwort hinzufügen?
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 wird Ihr Bild enthalten.

Noufal Ibrahim
quelle
2
Sie sollten die Datei im Binärmodus öffnen: open("file01.jpg", "wb")Andernfalls können Sie das Bild beschädigen.
Liquid_Fire
2
urllib.urlretrievekann das Bild direkt speichern.
Heltonbiker
17

Ich habe ein Skript geschrieben, das genau dies tut und das auf meinem Github für Sie verfügbar ist.

Ich habe BeautifulSoup verwendet, um jede Website nach Bildern zu analysieren. Wenn Sie viel Web-Scraping durchführen (oder mein Tool verwenden möchten), empfehle ich Ihnen sudo pip install BeautifulSoup. Informationen zu BeautifulSoup finden Sie hier .

Der Einfachheit halber ist hier mein 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')
Jep.
quelle
11

Dies kann mit Anfragen erfolgen. Laden Sie die Seite und sichern Sie den binären Inhalt in einer Datei.

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
quelle
1
Benutzer-Header in Anfragen, wenn eine schlechte Anfrage
eingeht
8

Python 3

urllib.request - Erweiterbare Bibliothek zum Öffnen von 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
SergO
quelle
6

Eine Lösung, die mit Python 2 und Python 3 funktioniert:

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")

oder wenn die zusätzliche Anforderung von requestsakzeptabel ist und wenn es sich um eine http (s) URL handelt:

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
quelle
5

Ich habe ein Skript erstellt, das das Skript von Yup erweitert. Ich habe einige Dinge repariert. Es wird jetzt 403: Verbotene Probleme umgangen. Es stürzt nicht ab, wenn ein Bild nicht abgerufen werden kann. Es wird versucht, beschädigte Vorschauen zu vermeiden. Es bekommt die richtigen absoluten URLs. Es gibt mehr Informationen. Es kann mit einem Argument über die Befehlszeile ausgeführt werden.

# 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
quelle
3

Anforderungsbibliothek verwenden

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
quelle
Es scheint, dass der Header in meinem Fall wirklich wichtig ist. Ich habe 403 Fehler erhalten. Es funktionierte.
Ishtiyaq Husain
2

Dies ist eine sehr kurze Antwort.

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

Version für Python 3

Ich habe den Code von @madprops für Python 3 angepasst

# 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
quelle
1

Etwas Neues für Python 3 mit Requests:

Kommentare im Code. Gebrauchsfertige Funktion.


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
quelle
0

Späte Antwort, aber python>=3.6Sie können dload verwenden , dh:

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

Wenn Sie das Bild als benötigen bytes, verwenden Sie:

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

installieren mit pip3 install dload

CONvid19
quelle
-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
quelle
4
Willkommen bei Stack Overflow! Während Sie möglicherweise das Problem dieses Benutzers gelöst haben, sind reine Code-Antworten für Benutzer, die in Zukunft auf diese Frage kommen, nicht sehr hilfreich. Bitte bearbeiten Sie Ihre Antwort, um zu erklären, warum Ihr Code das ursprüngliche Problem löst.
Joe C
1
TypeError: a bytes-like object is required, not 'Response'. Es muss seinhandler.write(img_data.content)
TitanFighter
Es sollte sein handler.write(img_data.read()).
jdhao