Ein Bild über Urllib und Python herunterladen

182

Ich versuche also, ein Python-Skript zu erstellen, das Webcomics herunterlädt und in einem Ordner auf meinem Desktop ablegt. Ich habe hier ein paar ähnliche Programme gefunden, die etwas Ähnliches tun, aber nichts Vergleichbares zu dem, was ich brauche. Die ähnlichste fand ich hier ( http://bytes.com/topic/python/answers/850927-problem-using-urllib-download-images ). Ich habe versucht, diesen Code zu verwenden:

>>> import urllib
>>> image = urllib.URLopener()
>>> image.retrieve("http://www.gunnerkrigg.com//comics/00000001.jpg","00000001.jpg")
('00000001.jpg', <httplib.HTTPMessage instance at 0x1457a80>)

Ich habe dann meinen Computer nach einer Datei "00000001.jpg" durchsucht, aber alles, was ich gefunden habe, war das zwischengespeicherte Bild davon. Ich bin mir nicht einmal sicher, ob die Datei auf meinem Computer gespeichert wurde. Sobald ich verstanden habe, wie die Datei heruntergeladen wird, weiß ich, wie ich mit dem Rest umgehen soll. Verwenden Sie im Wesentlichen einfach eine for-Schleife und teilen Sie die Zeichenfolge bei '00000000'. 'Jpg' und erhöhen Sie die '00000000' auf die größte Zahl, die ich irgendwie bestimmen müsste. Irgendwelche Empfehlungen, wie man das am besten macht oder wie man die Datei richtig herunterlädt?

Vielen Dank!

EDIT 15.06.10

Hier ist das fertige Skript, es speichert die Dateien in einem beliebigen Verzeichnis, das Sie auswählen. Aus irgendeinem Grund wurden die Dateien nicht heruntergeladen und sie haben es einfach getan. Vorschläge zur Bereinigung sind sehr willkommen. Ich arbeite derzeit daran, herauszufinden, wie viele Comics auf der Website vorhanden sind, damit ich nur die neuesten erhalten kann, anstatt das Programm nach einer bestimmten Anzahl von Ausnahmen beenden zu lassen.

import urllib
import os

comicCounter=len(os.listdir('/file'))+1  # reads the number of files in the folder to start downloading at the next comic
errorCount=0

def download_comic(url,comicName):
    """
    download a comic in the form of

    url = http://www.example.com
    comicName = '00000000.jpg'
    """
    image=urllib.URLopener()
    image.retrieve(url,comicName)  # download comicName at URL

while comicCounter <= 1000:  # not the most elegant solution
    os.chdir('/file')  # set where files download to
        try:
        if comicCounter < 10:  # needed to break into 10^n segments because comic names are a set of zeros followed by a number
            comicNumber=str('0000000'+str(comicCounter))  # string containing the eight digit comic number
            comicName=str(comicNumber+".jpg")  # string containing the file name
            url=str("http://www.gunnerkrigg.com//comics/"+comicName)  # creates the URL for the comic
            comicCounter+=1  # increments the comic counter to go to the next comic, must be before the download in case the download raises an exception
            download_comic(url,comicName)  # uses the function defined above to download the comic
            print url
        if 10 <= comicCounter < 100:
            comicNumber=str('000000'+str(comicCounter))
            comicName=str(comicNumber+".jpg")
            url=str("http://www.gunnerkrigg.com//comics/"+comicName)
            comicCounter+=1
            download_comic(url,comicName)
            print url
        if 100 <= comicCounter < 1000:
            comicNumber=str('00000'+str(comicCounter))
            comicName=str(comicNumber+".jpg")
            url=str("http://www.gunnerkrigg.com//comics/"+comicName)
            comicCounter+=1
            download_comic(url,comicName)
            print url
        else:  # quit the program if any number outside this range shows up
            quit
    except IOError:  # urllib raises an IOError for a 404 error, when the comic doesn't exist
        errorCount+=1  # add one to the error count
        if errorCount>3:  # if more than three errors occur during downloading, quit the program
            break
        else:
            print str("comic"+ ' ' + str(comicCounter) + ' ' + "does not exist")  # otherwise say that the certain comic number doesn't exist
print "all comics are up to date"  # prints if all comics are downloaded
Mike
quelle
Ok, ich habe sie alle zum Download! Jetzt bin ich mit einer sehr uneleganten Lösung festgefahren, um festzustellen, wie viele Comics online sind ... Ich führe das Programm im Grunde genommen auf eine Zahl aus, von der ich weiß, dass sie über der Anzahl der Comics liegt, und führe dann eine Ausnahme aus, die auftritt, wenn ein Comic nicht erscheint Es gibt keine Ausnahme, und wenn die Ausnahme mehr als zweimal auftritt (da ich nicht denke, dass mehr als zwei Comics fehlen werden), wird das Programm beendet, da keine weiteren zum Herunterladen verfügbar sind. Gibt es eine beste Möglichkeit, um festzustellen, wie viele Dateien sich auf der Website befinden, da ich keinen Zugriff auf die Website habe? Ich werde meinen Code in einer Sekunde veröffentlichen.
Mike
creativebe.com/icombiner/merge-jpg.html Mit diesem Programm habe ich alle JPG-Dateien zu einem PDF zusammengeführt. Funktioniert super und ist kostenlos!
Mike
6
Erwägen Sie, Ihre Lösung als Antwort zu veröffentlichen und aus der Frage zu entfernen. Frage Beiträge sind zum Stellen von Fragen, beantworten Beiträge für Antworten :-)
BartoszKP
warum ist das markiert mit beautifulsoup? Dieser Beitrag erscheint in der Liste der Top- beautifulsoupFragen
P0W
1
@ P0W Ich habe das besprochene Tag entfernt.
kmonsoor

Antworten:

250

Python 2

Verwenden von urllib.urlretrieve

import urllib
urllib.urlretrieve("http://www.gunnerkrigg.com//comics/00000001.jpg", "00000001.jpg")

Python 3

Die Verwendung von urllib.request.urlretrieve (Teil der Legacy-Oberfläche von Python 3 funktioniert genauso)

import urllib.request
urllib.request.urlretrieve("http://www.gunnerkrigg.com//comics/00000001.jpg", "00000001.jpg")
Matthew Flaschen
quelle
Es scheint die Dateierweiterung für mich abzuschneiden, wenn es als Argument übergeben wird (die Erweiterung ist in der ursprünglichen URL vorhanden). Irgendeine Idee warum?
Jeff Thompson
1
Mit freundlichen Grüßen, ja. Ich glaube, ich habe angenommen, dass die Dateierweiterung angehängt wird, wenn keine Dateierweiterung angegeben wird. Das hat mir damals Sinn gemacht, aber ich denke jetzt verstehe ich, was passiert.
Jeff Thompson
65
Hinweis für Python 3 müssten Sie [url.request] ( docs.python.org/3.0/library/… ) importieren :import urllib.request urllib.request.retrieve("http://...")
wasabigeek
1
Beachten Sie, dass die Python 3-Dokumentliste retrieve () als Teil einer "Legacy-Schnittstelle" verwendet wird und möglicherweise in Zukunft veraltet ist.
Nathan Wailes
18
Hinweis für Python 3 ist es tatsächlich import urllib.request urllib.request.urlretrieve("http://...jpg", "1.jpg"). Es ist urlretrievejetzt ab 3.x.
user1032613
81
import urllib
f = open('00000001.jpg','wb')
f.write(urllib.urlopen('http://www.gunnerkrigg.com//comics/00000001.jpg').read())
f.close()
DiGMi
quelle
67

Nur für den Datensatz, mit Anforderungsbibliothek.

import requests
f = open('00000001.jpg','wb')
f.write(requests.get('http://www.gunnerkrigg.com//comics/00000001.jpg').content)
f.close()

Es sollte jedoch nach dem Fehler request.get () suchen.

ellimilial
quelle
1
Selbst wenn diese Lösung nicht urllib verwendet, verwenden Sie möglicherweise bereits die Anforderungsbibliothek, die bereits in Ihrem Python-Skript enthalten ist (das war mein Fall bei der Suche danach), sodass Sie sie möglicherweise auch verwenden möchten, um Ihre Bilder abzurufen.
Iam Zesh
Vielen Dank, dass Sie diese Antwort über die anderen gestellt haben. Am Ende brauchte ich benutzerdefinierte Header, damit mein Download funktioniert, und der Zeiger auf die Anforderungsbibliothek verkürzte den Prozess, bei dem alles für mich funktioniert, erheblich.
Kuzzooroo
Urllib konnte nicht einmal in Python3 zum Laufen gebracht werden. Anfragen hatten keine Probleme und es ist bereits geladen! Die viel bessere Wahl denke ich.
user3023715
@ user3023715 in Python3 müssen Sie Anfrage von urllib importieren, siehe hier
Yassine Sedrani
34

Für Python 3 müssen Sie Folgendes importieren import urllib.request:

import urllib.request 

urllib.request.urlretrieve(url, filename)

Weitere Informationen finden Sie unter dem Link

HISI
quelle
15

Python 3-Version von @ DiGMis Antwort:

from urllib import request
f = open('00000001.jpg', 'wb')
f.write(request.urlopen("http://www.gunnerkrigg.com/comics/00000001.jpg").read())
f.close()
Dennis Golomazov
quelle
10

Ich habe diese Antwort gefunden und bearbeite sie zuverlässiger

def download_photo(self, img_url, filename):
    try:
        image_on_web = urllib.urlopen(img_url)
        if image_on_web.headers.maintype == 'image':
            buf = image_on_web.read()
            path = os.getcwd() + DOWNLOADED_IMAGE_PATH
            file_path = "%s%s" % (path, filename)
            downloaded_image = file(file_path, "wb")
            downloaded_image.write(buf)
            downloaded_image.close()
            image_on_web.close()
        else:
            return False    
    except:
        return False
    return True

Hieraus erhalten Sie beim Herunterladen keine anderen Ressourcen oder Ausnahmen.

Janith Chinthana
quelle
1
Sie sollten das 'Selbst' entfernen
Euphe
8

Wenn Sie wissen, dass sich die Dateien im selben Verzeichnis dirder Website befinden siteund das folgende Format haben: Dateiname_01.jpg, ..., Dateiname_10.jpg, laden Sie alle herunter:

import requests

for x in range(1, 10):
    str1 = 'filename_%2.2d.jpg' % (x)
    str2 = 'http://site/dir/filename_%2.2d.jpg' % (x)

    f = open(str1, 'wb')
    f.write(requests.get(str2).content)
    f.close()
len
quelle
7

Es ist am einfachsten, nur .read()die teilweise oder vollständige Antwort zu lesen und sie dann in eine Datei zu schreiben, die Sie an einem bekanntermaßen guten Ort geöffnet haben.

Ignacio Vazquez-Abrams
quelle
5

Vielleicht brauchen Sie 'User-Agent':

import urllib2
opener = urllib2.build_opener()
opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.137 Safari/537.36')]
response = opener.open('http://google.com')
htmlData = response.read()
f = open('file.txt','w')
f.write(htmlData )
f.close()
Alexander
quelle
Möglicherweise ist die Seite nicht verfügbar?
Alexander
3

Abgesehen davon, dass Sie die Dokumente retrieve()sorgfältig lesen ( http://docs.python.org/library/urllib.html#urllib.URLopener.retrieve ), würde ich vorschlagen, read()den Inhalt der Antwort tatsächlich aufzurufen und dann in zu speichern Eine Datei Ihrer Wahl, anstatt sie in der temporären Datei zu belassen, die beim Abrufen erstellt wird.

Gabriel Hurley
quelle
3

Bei allen oben genannten Codes kann der ursprüngliche Bildname nicht beibehalten werden, was manchmal erforderlich ist. Dies hilft beim Speichern der Images auf Ihrem lokalen Laufwerk, wobei der ursprüngliche Image-Name beibehalten wird

    IMAGE = URL.rsplit('/',1)[1]
    urllib.urlretrieve(URL, IMAGE)

Versuchen Sie dies für weitere Details.

Ojas
quelle
3

Dies funktionierte bei mir mit Python 3.

Es ruft eine Liste der URLs aus der CSV-Datei ab und lädt sie in einen Ordner herunter. Falls der Inhalt oder das Bild nicht existiert, nimmt es diese Ausnahme und macht weiter seine Magie.

import urllib.request
import csv
import os

errorCount=0

file_list = "/Users/$USER/Desktop/YOUR-FILE-TO-DOWNLOAD-IMAGES/image_{0}.jpg"

# CSV file must separate by commas
# urls.csv is set to your current working directory make sure your cd into or add the corresponding path
with open ('urls.csv') as images:
    images = csv.reader(images)
    img_count = 1
    print("Please Wait.. it will take some time")
    for image in images:
        try:
            urllib.request.urlretrieve(image[0],
            file_list.format(img_count))
            img_count += 1
        except IOError:
            errorCount+=1
            # Stop in case you reach 100 errors downloading images
            if errorCount>100:
                break
            else:
                print ("File does not exist")

print ("Done!")
Sieger
quelle
2

Eine einfachere Lösung kann sein (Python 3):

import urllib.request
import os
os.chdir("D:\\comic") #your path
i=1;
s="00000000"
while i<1000:
    try:
        urllib.request.urlretrieve("http://www.gunnerkrigg.com//comics/"+ s[:8-len(str(i))]+ str(i)+".jpg",str(i)+".jpg")
    except:
        print("not possible" + str(i))
    i+=1;
Ayush
quelle
Seien Sie vorsichtig bei der Verwendung eines Bare, außer so, siehe stackoverflow.com/questions/54948548/… .
AMC
1

Was ist damit:

import urllib, os

def from_url( url, filename = None ):
    '''Store the url content to filename'''
    if not filename:
        filename = os.path.basename( os.path.realpath(url) )

    req = urllib.request.Request( url )
    try:
        response = urllib.request.urlopen( req )
    except urllib.error.URLError as e:
        if hasattr( e, 'reason' ):
            print( 'Fail in reaching the server -> ', e.reason )
            return False
        elif hasattr( e, 'code' ):
            print( 'The server couldn\'t fulfill the request -> ', e.code )
            return False
    else:
        with open( filename, 'wb' ) as fo:
            fo.write( response.read() )
            print( 'Url saved as %s' % filename )
        return True

##

def main():
    test_url = 'http://cdn.sstatic.net/stackoverflow/img/favicon.ico'

    from_url( test_url )

if __name__ == '__main__':
    main()
gmas80
quelle
0

Wenn Sie Proxy-Unterstützung benötigen, können Sie dies tun:

  if needProxy == False:
    returnCode, urlReturnResponse = urllib.urlretrieve( myUrl, fullJpegPathAndName )
  else:
    proxy_support = urllib2.ProxyHandler({"https":myHttpProxyAddress})
    opener = urllib2.build_opener(proxy_support)
    urllib2.install_opener(opener)
    urlReader = urllib2.urlopen( myUrl ).read() 
    with open( fullJpegPathAndName, "w" ) as f:
      f.write( urlReader )
Eamonn Kenny
quelle
0

Eine andere Möglichkeit, dies zu tun, ist über die Fastai-Bibliothek. Das hat für mich wie ein Zauber gewirkt. Ich stand vor einer SSL: CERTIFICATE_VERIFY_FAILED ErrorVerwendung, urlretrievealso habe ich das versucht.

url = 'https://www.linkdoesntexist.com/lennon.jpg'
fastai.core.download_url(url,'image1.jpg', show_progress=False)
Sid
quelle
Ich hatte ein SSL: CERTIFICATE_VERIFY_FAILED Fehler stackoverflow.com/questions/27835619/…
AMC
0

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

if __name__ == '__main__':
    ImageDl(url)
Sohan Das
quelle
0

Mit urllib können Sie dies sofort erledigen.

import urllib.request

opener=urllib.request.build_opener()
opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1941.0 Safari/537.36')]
urllib.request.install_opener(opener)

urllib.request.urlretrieve(URL, "images/0.jpg")
Sreekant Shenoy
quelle