IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Télécharger zip et extraire les fichiers


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    SIGiste
    Inscrit en
    Juin 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : SIGiste

    Informations forums :
    Inscription : Juin 2018
    Messages : 8
    Par défaut Télécharger zip et extraire les fichiers
    Bonjour,

    Novice et autodidacte dans le langage python, je me tourne vers la communauté pour obtenir de l'aide sur un code qui doit me permettre de télécharger un fichier zip puis dans extraire l'ensemble de ces fichiers dans un dossier. Mon code est donc le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if os.path.exists(repertoire):
    	print ("dossier :  OK")
    else :
    	os.makedirs(repertoire)
     
    #  Téléchargement du fichier
    req = requests.get(url,stream=True)
    #  Extrait le ZIP
    zipfile= zipfile.ZipFile(BytesIO(req.content))
    zipfile.extractall(repertoire)
    La difficulté est qu'une fois sur 10, le traitement s'arrête soudainement et remonte des exceptions de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Traceback (most recent call last):
      File "C:\Program Files\QGIS 3.34.7\apps\Python312\Lib\site-packages\requests\models.py", line 816, in generate
        yield from self.raw.stream(chunk_size, decode_content=True)
      File "C:\Program Files\QGIS 3.34.7\apps\Python312\Lib\site-packages\urllib3\response.py", line 1040, in stream
        yield from self.read_chunked(amt, decode_content=decode_content)
      File "C:\Program Files\QGIS 3.34.7\apps\Python312\Lib\site-packages\urllib3\response.py", line 1184, in read_chunked
        self._update_chunk_length()
      File "C:\Program Files\QGIS 3.34.7\apps\Python312\Lib\site-packages\urllib3\response.py", line 1119, in _update_chunk_length
        raise ProtocolError("Response ended prematurely") from None
    urllib3.exceptions.ProtocolError: Response ended prematurely
     
    During handling of the above exception, another exception occurred:
     
    Traceback (most recent call last):
      File "C:\Script\SUP\geo_sup.py", line 125, in <module>
        zipfile= zipfile.ZipFile(BytesIO(req.content))
                                         ^^^^^^^^^^^
      File "C:\Program Files\QGIS 3.34.7\apps\Python312\Lib\site-packages\requests\models.py", line 899, in content
        self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Program Files\QGIS 3.34.7\apps\Python312\Lib\site-packages\requests\models.py", line 818, in generate
        raise ChunkedEncodingError(e)
    requests.exceptions.ChunkedEncodingError: Response ended prematurely
    J'ai écumé les différentes discussions notamment celle-ci :

    https://stackoverflow.com/questions/...-with-requests

    Néanmoins, j'ai quelques difficultés à assimiler le problème, ( il semble que ce soit lié à la tache qui demande des ressources mémoires au dela de la limite autorisée) et à le résoudre.

    Pouvez-vous m'aider à ce sujet ?

    D'avance un grand

  2. #2
    Expert confirmé Avatar de papajoker
    Homme Profil pro
    Développeur Web
    Inscrit en
    Septembre 2013
    Messages
    2 284
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2013
    Messages : 2 284
    Par défaut
    bonjour

    Ta seule erreur ici est web urllib3... procolole erreur (pas merci pour ta copie écran, je ne peux faire un copier/coller de ton erreur ou, facilement indiquer le ligne)

    La seconde erreur (normale) est uniquement parce que tu ne testes pas le retour de ta méthode requests.get() et essayes de décompresser même si le fichier n'est pas arrivé.

    Pour la mémoire ... tu n'indiques rien (taille fichier, ram disponible) que veux-tu que l'on réponde ? si le fichier fait 8Go, effectivement

    Note: Que vient faire ton paramètre stream ?? était avant ton erreur ? ou est une mauvaise copie depuis ton lien après erreur ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    SIGiste
    Inscrit en
    Juin 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : SIGiste

    Informations forums :
    Inscription : Juin 2018
    Messages : 8
    Par défaut
    Citation Envoyé par papajoker Voir le message
    bonjour

    Ta seule erreur ici est web urllib3... procolole erreur (pas merci pour ta copie écran, je ne peux faire un copier/coller de ton erreur ou, facilement indiquer le ligne)

    La seconde erreur (normale) est uniquement parce que tu ne testes pas le retour de ta méthode requests.get() et essayes de décompresser même si le fichier n'est pas arrivé.
    Ok le contenu de l'erreur est plus clair. Je vais gratter la dessus. et désolé pour la capture d'écran, je vais régler ça .

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    SIGiste
    Inscrit en
    Juin 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : SIGiste

    Informations forums :
    Inscription : Juin 2018
    Messages : 8
    Par défaut
    Bonjour,

    J'ai trouvé une discussion où l'on conseillait à la personne qui avait un message d'erreur tel que le mien de faire une boucle qui retente de télécharger le fichier en cas d'erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for essai in range(3):
        try:
            req = requests.get(url)
    	zipfile= zipfile.ZipFile(BytesIO(req.content))
    	zipfile.extractall(repertoire)
            break
        except requests.exceptions.ChunkedEncodingError:
            time.sleep(1)
    else:
        print("telechargement infructueux")
    C'est malheureusement une solution un peu biaisée car ça ne regle pas l'essence du problème.

  5. #5
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 503
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 503
    Par défaut
    le paramètre stream de requests.get fait que l'on attend pas la fin du téléchargement pour que la fonction retourne quelque chose; ça permet de télécharger par morceaux et éventuellement de s'arrêter avant la fin du téléchargement complet.

    https://realpython.com/python-download-file-from-url/

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    SIGiste
    Inscrit en
    Juin 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : SIGiste

    Informations forums :
    Inscription : Juin 2018
    Messages : 8
    Par défaut
    Bonjour,

    Je reviens vers vous toujours avec mes lacunes en python car cette fois je souhaiterais télécharger des archives provenant de différentes url. J'ai donc pensé à créer une boucle de ce genre pour arriver à mon but :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    liste = [urlIA4,urlA5]
     
    for i in liste :
        req = requests.get(i)
        zipfile= zipfile.ZipFile(BytesIO(req.content))
        zipfile.extractall(repertoire)
    Malheureusement, cela ne me télécharge et extrait que le fichier de la première url et j'essuie ce message d'erreur :

    Traceback (most recent call last):
    File "C:\Script\SUP\debug_geo_sup_v2.py", line 115, in <module>
    zipfile= zipfile.ZipFile(BytesIO(req.content))
    ^^^^^^^^^^^^^^^
    AttributeError: 'ZipFile' object has no attribute 'ZipFile'
    Je suppose qu'il ne doit pas comprendre avec ce simple code qu'il doit faire les deux dernières étapes avec la deuxième valeur de la liste.

    Si une âme charitable veut me bien un coup de main, je lui en serais reconnaissant.

    Merci d'avance à vous.

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 032
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 032
    Par défaut
    Hello,

    Dans ta boucle, tu fais zipfile = zipfile.ZipFile(...).

    Une fois cette ligne exécutée, zipfile ne représente plus le module zipfile mais un objet ZipFile, ce qui cause l'erreur d'attribut à l'itération suivante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import requests
    import zipfile
    from io import BytesIO
     
     
    liste = [urlIA4, urlA5]
    repertoire = "chemin/vers/le/dossier"
     
     
    for url in liste:
        req = requests.get(url)
     
        if req.status_code == 200:  # Vérifier si la requête a réussi
            with zipfile.ZipFile(BytesIO(req.content)) as archive:
                archive.extractall(repertoire)
            print(f"Extraction réussie pour {url}")
        else:
            print(f"Erreur lors du téléchargement de {url} : {req.status_code}")
    Utilisation de with zipfile.ZipFile(...) :

    • Cela garantit que l'archive ZIP est bien fermée après extraction.

    Ajout d'un test sur le status_code :

    • Si l'URL ne répond pas correctement (404, 500, etc.), cela évite de tenter d'ouvrir un fichier ZIP corrompu.
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    SIGiste
    Inscrit en
    Juin 2018
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : SIGiste

    Informations forums :
    Inscription : Juin 2018
    Messages : 8
    Par défaut
    Bonjour Fred,

    Merci pour ton retour.

    Je comprends mon erreur.
    J'assimile le tout et teste.

    Merci de nouveau

Discussions similaires

  1. Réponses: 5
    Dernier message: 16/07/2015, 13h50
  2. Extraire les fichiers d'un zip distant
    Par Ceubex dans le forum Bibliothèques et frameworks
    Réponses: 0
    Dernier message: 03/07/2013, 13h10
  3. [backup] Est il possible d'extraire les fichiers d'un backup ?
    Par zoltix dans le forum Administration
    Réponses: 3
    Dernier message: 18/08/2011, 15h35
  4. Extraire les fichiers d'une arborescence
    Par Tristan Zwingelstein dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 30/04/2011, 18h00
  5. Réponses: 7
    Dernier message: 15/09/2010, 01h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo