2014-05-02 22 views
10

Vorrei scaricare un file zip da internet ed estrarlo.Scaricare un file zip ed estrarlo in memoria usando Python3

Preferisco utilizzare le richieste. Non voglio scrivere sul disco.

Sapevo come farlo in Python2, ma sono senza tracce per python3.3. Apparentemente, zipfile.Zipfile vuole un oggetto simile a un file, ma non so come ottenerlo da quali richieste vengono restituite.

Se sai come farlo con urllib.request, sarei curioso di vedere come lo fai anche tu.

risposta

27

ho scoperto come si fa:

request = requests.get(url) 
file = zipfile.ZipFile(BytesIO(request.content)) 

quello che mi mancava:

  • request.content deve essere utilizzato per accedere ai byte
  • io.BytesIO è l'oggetto file simile per bytes.
+0

Sono d'accordo, la mia formulazione si riferiva a qualche tipo di magia nera :) Grazie per la precisione! – user1720740

+0

Ciao, questa soluzione è compatibile anche con Python 2.7 ?? –

+0

Per rendere più chiaro me stesso utilizzando parti della risposta di @ aonbyte: 'zipDocument = zipfile.ZipFile (io.BytesIO (request.content))' e quindi estrarre/salvarlo: 'zipDocument.extractall()' –

5

Utilizzando Richieste, questo può essere fatto in modo molto semplice.

import requests, zipfile, StringIO 
response = requests.get(zip_file_url) 
zipDocument = zipfile.ZipFile(StringIO.StringIO(response.content)) 

Utilizzando String.IO è possibile creare un oggetto di tipo file per l'attributo del contenuto delle risposte.

Se si desidera estrarre alla directory è possibile utilizzare extractall del ZipFile() funzione

zipDocment.extractall() 
+0

Non c'è StringIO.StringIO in python3. Si potrebbe usare io.StringIO. Ciò fallisce miseramente sulla mia installazione. Forse c'è qualcosa di sbagliato nella mia installazione: TypeError: initial_value deve essere str o None, non byte – user1720740

+1

-1, questo non funziona in Python 3 - StringIO prende un str mentre sia 'ZipFile' che' response.content' richiedono byte. 'io.ByteIO' è la cosa da usare – dbr

+0

Ci sono errori nella risposta e il commento di @dbr: dovrebbe essere' zipDocument.extractall() 'e' io.BytesIO'. I.e., zipfile.ZipFile (io.BytesIO (response.content)) '(_note: non può modificare la risposta_) –

5

Ecco un altro approccio risparmiando dover installare richieste:

r = urllib.request.urlopen(req) 
    with zipfile.ZipFile(BytesIO(r.read())) as z: 
     print(z.namelist()) 
+0

Perché il down vote ? – Baz

+0

Ti darò un upvote quindi almeno non è <0, penso che sia una buona risposta, anche se preferisco usare le richieste :) – zapatilla