• 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 le Content-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 like http://url.com/download. In that case, the Content-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 :
      liste des URLs de la catégorie road fournie par ImageNet que nous utilisons pour télécharger des images à partir d'URLs

       

      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

      urllib sera utilisée afin de pouvoir interagir avec les URLs. NumPy pour 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.

 

Aucun commentaire

 

Laissez un commentaire