2013-03-12 8 views
24

Ich möchte eine Datei mit Urllib herunterladen und die Datei im Speicher vor dem Speichern dekomprimieren.Herunterladen und entpacken gezippte Datei im Speicher?

Das ist, was ich jetzt haben:

response = urllib2.urlopen(baseURL + filename) 
compressedFile = StringIO.StringIO() 
compressedFile.write(response.read()) 
decompressedFile = gzip.GzipFile(fileobj=compressedFile, mode='rb') 
outfile = open(outFilePath, 'w') 
outfile.write(decompressedFile.read()) 

Damit endet leere Dateien zu schreiben auf. Wie kann ich erreichen, wonach ich suche?

Aktualisiert Antwort:

#! /usr/bin/env python2 
import urllib2 
import StringIO 
import gzip 

baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/" 
filename = "man-pages-3.34.tar.gz" 
outFilePath = filename[:-3] 

response = urllib2.urlopen(baseURL + filename) 
compressedFile = StringIO.StringIO(response.read()) 
decompressedFile = gzip.GzipFile(fileobj=compressedFile) 

with open(outFilePath, 'w') as outfile: 
    outfile.write(decompressedFile.read()) 
+0

was mit Dekomprimierung auf die Festplatte falsch? – MattDMo

+2

Ich dekomprimiere auf die Festplatte, lasse die komprimierten Bytes einfach nicht auf die Festplatte fallen. – OregonTrail

+0

wird 'compressedFile' jemals in die Datenbank eingefügt? – MattDMo

Antwort

35

Sie müssen Anfang compressedFile nach ihm zu suchen, zu schreiben, aber bevor es zu gzip.GzipFile() vorbei. Andernfalls wird es am Ende von gzip Modul gelesen und wird als eine leere Datei angezeigt. Siehe unten:

#! /usr/bin/env python 
import urllib2 
import StringIO 
import gzip 

baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/" 
filename = "man-pages-3.34.tar.gz" 
outFilePath = "man-pages-3.34.tar" 

response = urllib2.urlopen(baseURL + filename) 
compressedFile = StringIO.StringIO() 
compressedFile.write(response.read()) 
# 
# Set the file's current position to the beginning 
# of the file so that gzip.GzipFile can read 
# its contents from the top. 
# 
compressedFile.seek(0) 

decompressedFile = gzip.GzipFile(fileobj=compressedFile, mode='rb') 

with open(outFilePath, 'w') as outfile: 
    outfile.write(decompressedFile.read()) 
+4

Es stellte sich heraus, dass ich StringIOs "__init__" hätte nutzen können, siehe aktualisierte Frage. – OregonTrail

+0

Ja. Das funktioniert noch besser. :) Ich werde meine Antwort unbearbeitet lassen, da Sie bereits die aktualisierte Antwort hinzugefügt haben. Vielen Dank. – crayzeewulf

+0

@OregonTrail: oder Sie könnten den Zwischenhändler ausschneiden und [Antwort direkt übergeben] (http://stackoverflow.com/a/26435241/4279). Btw, setzen Sie * Antworten * nicht in die Frage ein; [Sie werden aufgefordert, Ihre eigene Antwort zu veröffentlichen] (http://stackoverflow.com/help/self-answer). – jfs

9

Für diejenigen mit Python 3, die äquivalente Antwort lautet:

import urllib.request 
import io 
import gzip 

response = urllib.request.urlopen(FILE_URL) 
compressed_file = io.BytesIO(response.read()) 
decompressed_file = gzip.GzipFile(fileobj=compressed_file) 

with open(OUTFILE_PATH, 'wb') as outfile: 
    outfile.write(decompressed_file.read()) 
+0

wird es nicht funktionieren: Sie versuchen, Bytes in eine Textdatei zu schreiben; Verwenden Sie stattdessen den Binärmodus. Probieren Sie: 'copyfileobj (GzipFile (fileobj = Antwort), öffnen (outfile_path, 'wb'))' – jfs

6

Wenn Sie Python 3.2 oder höher, wäre das Leben viel einfacher:

#!/usr/bin/env python3 
import gzip 
import urllib.request 

baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/" 
filename = "man-pages-4.03.tar.gz" 
outFilePath = filename[:-3] 

response = urllib.request.urlopen(baseURL + filename) 
with open(outFilePath, 'wb') as outfile: 
    outfile.write(gzip.decompress(response.read())) 

Für diejenigen, die sich für Geschichte interessieren, siehe https://bugs.python.org/issue3488 und https://hg.python.org/cpython/rev/3fa0a9553402.

-2

Eine Zeile Code, der die entpackte Datei Inhalt drucken:

print gzip.GzipFile(fileobj=StringIO.StringIO(urllib2.urlopen(DOWNLOAD_LINK).read()), mode='rb').read()