217 votes

Téléchargement d'une image via urllib et python

J'essaie donc de faire un script Python qui télécharge les webcomics et les met dans un dossier sur mon bureau. J'ai trouvé quelques programmes similaires sur ici qui font quelque chose de similaire, mais rien de tout à fait comme ce dont j'ai besoin. Celui que j'ai trouvé le plus similaire est juste ici ( http://bytes.com/topic/python/answers/850927-problem-using-urllib-download-images ). J'ai essayé d'utiliser ce code :

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

J'ai ensuite cherché dans mon ordinateur le fichier "00000001.jpg", mais je n'ai trouvé que l'image en cache de celui-ci. Je ne suis même pas sûr qu'il ait enregistré le fichier sur mon ordinateur. Une fois que j'ai compris comment obtenir le téléchargement du fichier, je pense savoir comment gérer le reste. Essentiellement, il suffit d'utiliser une boucle for et de diviser la chaîne au niveau de '00000000'.'jpg' et d'incrémenter le '00000000' jusqu'au plus grand nombre, que je devrais déterminer d'une manière ou d'une autre. Avez-vous des recommandations sur la meilleure façon de procéder ou sur la manière de télécharger le fichier correctement ?

Merci !

EDIT 15/06/10

Voici le script terminé, il enregistre les fichiers dans le répertoire de votre choix. Pour une raison étrange, les fichiers n'étaient pas téléchargés et ils l'ont juste fait. Toute suggestion sur la façon de le nettoyer serait très appréciée. Je travaille actuellement sur la façon de déterminer le nombre de bandes dessinées existant sur le site afin de pouvoir récupérer la dernière, plutôt que de faire quitter le programme après un certain nombre d'exceptions.

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

0 votes

Ok, je les ai tous téléchargés ! Maintenant, je suis coincé avec une solution très inélégante pour déterminer combien de BD sont en ligne... En gros, je lance le programme jusqu'à un nombre que je sais supérieur au nombre de BD et je lance une exception pour qu'elle apparaisse lorsqu'une BD n'existe pas, et lorsque l'exception apparaît plus de deux fois (puisque je ne pense pas qu'il manque plus de deux BD), le programme s'arrête, pensant qu'il n'y a plus de BD à télécharger. Comme je n'ai pas accès au site web, existe-t-il un meilleur moyen de déterminer le nombre de fichiers présents sur le site ? Je vais poster mon code dans une seconde.

0 votes

creativebe.com/icombiner/merge-jpg.html J'ai utilisé ce programme pour fusionner tous les fichiers .jpg en un seul PDF. Ça marche super bien, et c'est gratuit !

10 votes

Envisagez de poster votre solution en tant que réponse, et de la retirer de la question. Les messages de questions servent à poser des questions, les messages de réponses à donner des réponses :-)

294voto

Matthew Flaschen Points 131723

Python 2

Utilisation de urllib.urlretrieve

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

Python 3

Utilisation de urllib.request.urlretrieve (fait partie de l'interface héritée de Python 3, fonctionne exactement de la même manière)

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

0 votes

Il semble que l'extension du fichier soit coupée lorsqu'elle est passée comme argument (l'extension est présente dans l'URL d'origine). Savez-vous pourquoi ?

0 votes

@JeffThompson, non. L'exemple (dans ma réponse) fonctionne-t-il pour vous (il fonctionne pour moi avec Python 2.7.8) ? Notez comment il spécifie l'extension explicitement pour le fichier local.

1 votes

Le vôtre, oui. Je pense que j'ai supposé que si aucune extension de fichier n'était donnée, l'extension du fichier serait ajoutée. Cela me paraissait logique à l'époque, mais je crois que je comprends maintenant ce qui se passe.

99voto

DiGMi Points 1404
import urllib
f = open('00000001.jpg','wb')
f.write(urllib.urlopen('http://www.gunnerkrigg.com//comics/00000001.jpg').read())
f.close()

82voto

ellimilial Points 262

Juste pour info, j'utilise la bibliothèque des demandes.

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

Pourtant, il devrait vérifier l'erreur requests.get().

1 votes

Même si cette solution n'utilise pas urllib, il se peut que vous utilisiez déjà la bibliothèque requests dans votre script de python (c'était mon cas en cherchant cela) donc vous pourriez l'utiliser aussi pour obtenir vos images.

0 votes

Merci d'avoir posté cette réponse en plus des autres. J'ai fini par avoir besoin d'en-têtes personnalisés pour que mon téléchargement fonctionne, et le pointeur vers la bibliothèque de requêtes a considérablement raccourci le processus pour que tout fonctionne pour moi.

0 votes

Je n'ai même pas réussi à faire fonctionner urllib dans python3. Requests n'a eu aucun problème et il est déjà chargé ! Un bien meilleur choix, je pense.

10voto

Janith Chinthana Points 936

J'ai trouvé ceci réponse et j'édite cela de manière plus fiable

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

Ainsi, vous n'obtiendrez jamais d'autres ressources ou exceptions lors du téléchargement.

2 votes

Vous devriez enlever le "self

8voto

Le plus simple est d'utiliser .read() pour lire la réponse partielle ou complète, puis l'écrire dans un fichier que vous avez ouvert à un endroit connu.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X