106 votes

Télécharger le fichier Zip retourné depuis l'URL

Si j'ai une URL qui, lorsqu'elle est soumise dans un navigateur web, fait apparaître une boîte de dialogue permettant d'enregistrer un fichier zip, comment puis-je attraper et télécharger ce fichier zip en Python ?

1 votes

J'ai essayé la section Télécharger un fichier binaire et l'écrire sur le disque de cette page qui a fonctionné comme un chram.

235voto

yoavram Points 347

D'après ce que je sais, la bonne façon de faire est :

import requests, zipfile, StringIO
r = requests.get(zip_file_url, stream=True)
z = zipfile.ZipFile(StringIO.StringIO(r.content))
z.extractall()

bien sûr, vous voudrez vérifier que le GET a réussi avec r.ok .

Pour python 3+, sous le module StringIO avec la commande io et utiliser BytesIO au lieu de StringIO : Ici sont des notes de version qui mentionnent ce changement.

import requests, zipfile, io
r = requests.get(zip_file_url)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall("/path/to/destination_directory")

50voto

senderle Points 41607

La plupart des gens recommandent d'utiliser requests s'il est disponible, et le requests documentation recommande ceci pour télécharger et sauvegarder des données brutes à partir d'une url :

import requests 

def download_url(url, save_path, chunk_size=128):
    r = requests.get(url, stream=True)
    with open(save_path, 'wb') as fd:
        for chunk in r.iter_content(chunk_size=chunk_size):
            fd.write(chunk)

Puisque la réponse demande de télécharger et l'épargne le fichier zip, je ne suis pas entré dans les détails concernant la lecture du fichier zip. Consultez l'une des nombreuses réponses ci-dessous pour connaître les possibilités.

Si pour une raison quelconque vous n'avez pas accès à requests vous pouvez utiliser urllib.request à la place. Il se peut qu'elle ne soit pas aussi robuste que la précédente.

import urllib.request

def download_url(url, save_path):
    with urllib.request.urlopen(url) as dl_file:
        with open(save_path, 'wb') as out_file:
            out_file.write(dl_file.read())

Enfin, si vous utilisez encore Python 2, vous pouvez utiliser urllib2.urlopen .

from contextlib import closing

def download_url(url, save_path):
    with closing(urllib2.urlopen(url)) as dl_file:
        with open(save_path, 'wb') as out_file:
            out_file.write(dl_file.read())

14voto

Jeremiah England Points 451

Avec l'aide de cet article de blog J'ai réussi à le faire fonctionner avec juste requests . L'intérêt de l'étrange stream c'est pour qu'on n'ait pas besoin d'appeler content sur les grosses demandes, ce qui nécessiterait de tout traiter en même temps, encombrant la mémoire. Le site stream évite cela en itérant dans les données, un morceau à la fois.

url = 'https://www2.census.gov/geo/tiger/GENZ2017/shp/cb_2017_02_tract_500k.zip'
target_path = 'alaska.zip'

response = requests.get(url, stream=True)
handle = open(target_path, "wb")
for chunk in response.iter_content(chunk_size=512):
    if chunk:  # filter out keep-alive new chunks
        handle.write(chunk)
handle.close()

11voto

Webucator Points 808

Voici ce que j'ai réussi à faire fonctionner en Python 3 :

import zipfile, urllib.request, shutil

url = 'http://www....myzipfile.zip'
file_name = 'myzip.zip'

with urllib.request.urlopen(url) as response, open(file_name, 'wb') as out_file:
    shutil.copyfileobj(response, out_file)
    with zipfile.ZipFile(file_name) as zf:
        zf.extractall()

0 votes

Bonjour. Comment éviter cette erreur : urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop. ?

0 votes

@VictorHerasmePerez, un code de statut de réponse HTTP 302 signifie que la page a été déplacée. Je pense que le problème que vous rencontrez est traité ici : stackoverflow.com/questions/32569934/

0 votes

@Webucator Si le dossier compressé contient plusieurs fichiers, tous ces fichiers seront extraits et stockés dans le système. Y a-t-il un moyen d'y parvenir ?

6voto

aravenel Points 328

Soit vous utilisez urllib2.urlopen, soit vous pouvez essayer d'utiliser l'excellent logiciel Requests et éviter les maux de tête liés à urllib2 :

import requests
results = requests.get('url')
#pass results.content onto secondary processing...

1 votes

Mais comment analyser results.content dans un zip ?

0 votes

Utilisez le zipfile module : zip = zipfile.ZipFile(results.content) . Ensuite, il suffit d'analyser les fichiers en utilisant ZipFile.namelist() , ZipFile.open() ou ZipFile.extractall()

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