-
PYTHON > Télécharger des fichiers
TELECHARGER DES FICHIERS
import urllib urllib.urlretrieve ("http://randomsite.com/file.gz", "file.gz")
—
import requests response = requests.get('http://www.example.com/image.jpg', stream=True) # Throw an error for bad status codes response.raise_for_status() with open('output.jpg', 'wb') as handle: for block in response.iter_content(1024): handle.write(block)
—
TELECHARGER DES FICHIERS BINAIRES
import requests url = 'http://google.com/favicon.ico' r = requests.get(url, allow_redirects=True) open('google.ico', 'wb').write(r.content)
Avec https://www.youtube.com/watch?v=9bZkp7q19f0.
Lorsqu’une URL poijte vers une page web plutôt qu’un fichier binaire, I had to not download that file and just keep the link as is.
Il faut inspecter l’en-tête (headers) avec leContent-Type
:r = requests.get(url, allow_redirects=True) print r.headers.get('content-type')
ça fonctionne, mais pas de façon optimum : Si le fichier est volumineux, rien ne se passe et gaspille de la bande passante.
Soluce : just fetching the headers of a url before actually downloading it. This allows us to skip downloading files which weren’t meant to be downloaded :import requests def is_downloadable(url): """ Does the url contain a downloadable resource """ h = requests.head(url, allow_redirects=True) header = h.headers content_type = header.get('content-type') if 'text' in content_type.lower(): return False if 'html' in content_type.lower(): return False return True print is_downloadable('https://www.youtube.com/watch?v=9bZkp7q19f0') False print is_downloadable('http://google.com/favicon.ico') True
To restrict download by file size, we can get the filesize from the
Content-Length
header and then do suitable comparisons :content_length = header.get('content-length', None) if content_length and content_length > 2e8: # 200 mb approx return False
So using the above function, we can skip downloading urls which don’t link to media.
Getting filename from URL
We can parse the url to get the filename. Example - http://aviaryan.in/images/profile.png.
To extract the filename from the above URL we can write a routine which fetches the last string after backslash (/).
url = 'http://aviaryan.in/images/profile.png' if url.find('/'): print url.rsplit('/', 1)[1]
This will be give the filename in some cases correctly. However, there are times when the filename information is not present in the url.
Example, something likehttp://url.com/download
. In that case, theContent-Disposition
header will contain the filename information.
Here is how to fetch it.import requests import re def get_filename_from_cd(cd): if not cd: return None fname = re.findall('filename=(.+)', cd) if len(fname) == 0: return None return fname[0] url = 'http://google.com/favicon.ico' r = requests.get(url, allow_redirects=True) filename = get_filename_from_cd(r.headers.get('content-disposition')) open(filename, 'wb').write(r.content)
The url-parsing code in conjuction with the above method to get filename from
Content-Disposition
header will work for most of the cases.
Use them and test the results.These are my 2 cents on downloading files using requests in Python. Let me know of other tricks I might have overlooked.
how to download multiple files from any website ?
dirs = ['dir1', 'dir2'] for dir in dirs: url = 'myurl/' + dir r = requests.get(url, allow_redirects=True) filename = get_filename_from_cd(r.headers.get('content-disposition')) open(filename, 'wb').write(r.content)
TELECHARGER DES IMAGES
Récupérer la liste des URL d’images
En cliquant dans la catégorie road, nous pouvons accéder à un onglet « Downloads » et nous pouvons obtenir les URLs des 1288 images de cette catégorie :
Nous aurons besoin de l’URL de cette page afin de pouvoir récupérer la liste des URLs des images. Dans le cas des routes, l’URL de cette catégorie est : http://image-net.org/api/text/imagenet.synset.geturls?wnid=n04096066
Téléchargement des images à partir d’URLs
urllibsera utilisée afin de pouvoir interagir avec les URLs.NumPypour convertir des séquences d’octets en tableaux NumPy lors du téléchargement.import urllib.request import cv2 import numpy as np
Création d’un fonction de téléchargement d’image
Nous créons ensuite une fonction image_from_url, qui nous permettra de télécharger les images à partir d’une URL.
Nous récupérons les données contenues à l’URL fournie ligne 6. Cette fonction nous renvoyant des octets, nous devons les convertir grâce à la fonction np.asarray (l.7) afin d’obtenir un tableau exploitable avec OpenCV. Cependant, le tableau que nous obtenons est un tableau à une dimension. C’est pourquoi nous appelons la fonction cv2.imdecode, en prenant en compte que nous avons une image couleur(l.8). Enfin, nous retournons l’image obtenue à partir de l’URL.
def image_from_url(url): rep = urllib.request.urlopen(url).read() image = np.asarray(bytearray(rep), dtype="uint8") image = cv2.imdecode(image, cv2.IMREAD_COLOR) return image
Nous avons maintenant une fonction qui nous permet de télécharger une image à partir d’une URL. Il ne nous reste plus qu’à télécharger toutes les images provenant de notre liste d’URL.
Parcours des différentes URLs
Pour ce faire, nous commençons par initialiser 2 variables: repertoire (l.11), qui permet de spécifier dans quel dossier nous voulons stocker les images et lien_img (l.12) qui est notre URL générale, identifiée à l’étape 1.
repertoire='Images/' lien_img="http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=n04096066" img_url=urllib.request.urlopen(lien_img).read().decode() i=0 for url in img_url.split('\n'): chemin=repertoire+'image_'+str(i)+'.jpg' image=image_from_url(url) cv2.imwrite(chemin,image) i+=1
Nous récupérons ensuite la liste des URLs sur la page lien_url ligne 14.
Puis nous parcourons chacune de ces URL grâce à la ligne 16. Pour chacune de ces URL, nous commençons par affecter un nom (et nous associons le répertoire afin d’obtenir le chemin où sauvegarder l’image) à chaque nouvelle image en utilisant une variable i qui est incrémentée à chaque itération (l.20).
Enfin, il ne nous reste plus qu’à appeler notre fonction image_from_url à la ligne 18 et à sauvegarder l’image à la ligne 19.
Tout est prêt, nous pouvons lancer notre programme pour télécharger les images à partir d’URLs.
Et si un lien est mort ?
Et au bout de quelques temps, nous rencontrerons un problème.
L’erreur 404 nous indique qu’une des images de notre liste n’existe plus. Nous allons donc modifier notre code afin de passer outre ces erreurs.
for url in img_url.split('\n'): try: chemin=repertoire+'image_'+str(i)+'.jpg' image=image_from_url(url) cv2.imwrite(chemin,image) i+=1 except: pass
Nous intégrons donc un bloc try, qui nous permet d’essayer de récupérer une image. Si une URL n’est plus valide, ce n’est pas grave, nous passons à la suivante. De cette façon, notre programme ne s’arrêtera pas si une image est introuvable.