Laden Sie die zurückgegebene Zip-Datei von der URL herunter

86

Wenn ich eine URL habe, die beim Senden in einem Webbrowser ein Dialogfeld zum Speichern einer Zip-Datei öffnet, wie würde ich diese Zip-Datei in Python abrufen und herunterladen?

user1229108
quelle
1
Ich habe versucht , Abschnitt eine binäre Datei herunterladen und auf der Festplatte zu schreiben von dieser Seite , die als chram gearbeitet.
Zeinab Abbasimazar

Antworten:

34

Die meisten Benutzer empfehlen die Verwendung, requestssofern verfügbar, und in der requests Dokumentation wird dies zum Herunterladen und Speichern von Rohdaten von einer URL empfohlen:

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)

Da in der Antwort nach dem Herunterladen und Speichern der Zip-Datei gefragt wird , habe ich keine Details zum Lesen der Zip-Datei angegeben. In einer der vielen Antworten unten finden Sie Möglichkeiten.

Wenn Sie aus irgendeinem Grund keinen Zugriff haben requests, können Sie verwendenurllib.request stattdessen verwenden. Es ist möglicherweise nicht ganz so robust wie oben.

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())

Wenn Sie Python 2 noch verwenden, können Sie es schließlich verwenden 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())
senderle
quelle
Können Sie bitte auch das Beispiel-Snippet hinzufügen? Es wäre so nett von Ihnen, dies zu tun
Sarvagya Dubey
206

Soweit ich das beurteilen kann, ist der richtige Weg, dies zu tun:

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

Natürlich möchten Sie überprüfen, ob das GET erfolgreich war r.ok.

Unterteilen Sie für Python 3+ das StringIO-Modul mit dem io- Modul und verwenden Sie BytesIO anstelle von StringIO: Hier finden Sie Versionshinweise , in denen diese Änderung erwähnt wird.

import requests, zipfile, io
r = requests.get(zip_file_url)
z = zipfile.ZipFile(io.BytesIO(r.content))
z.extractall("/path/to/destination_directory")
Yoavram
quelle
Danke für diese Antwort. Ich habe es verwendet, um mein Problem zu lösen und eine Zip-Datei mit Anfragen zu erhalten .
gr1zzly be4r
yoavram, in deinem Code - wo gebe ich die URL der Webseite ein?
NewGIS
25
Wenn Sie die heruntergeladene Datei an einem anderen Ort z.extractall()z.extractall("/path/to/destination_directory")
speichern möchten
1
Wenn Sie die Datei nur über die URL speichern möchten, haben Sie folgende Möglichkeiten : urllib.request.urlretrieve(url, filename).
Yoavram
3
Um anderen zu helfen, die Punkte zu verbinden, habe ich 60 Minuten zu lange gebraucht pd.read_table(z.open('filename')). Sie können sie dann mit den oben genannten verwenden. Nützlich, wenn Sie einen Zip-URL-Link haben, der mehrere Dateien enthält, und nur eine laden möchten.
Frikster
13

Mit Hilfe dieses Blog-Beitrags habe ich es nur zum Laufen gebracht requests. Der Sinn der seltsamen streamSache ist, dass wir keine contentgroßen Anfragen aufrufen müssen , die erfordern würden, dass alle auf einmal verarbeitet werden, was den Speicher verstopft. Das streamvermeidet dies, indem es die Daten Stück für Stück durchläuft.

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()
Jeremiah England
quelle
2
Antworten sollten für den Großteil ihres Inhalts nicht auf Links beruhen. Links können tot sein oder der Inhalt auf der anderen Seite kann geändert werden, um die Frage nicht mehr zu beantworten. Bitte bearbeiten Sie Ihre Antwort, um eine Zusammenfassung oder Erläuterung der Informationen zu enthalten, auf die Sie verweisen.
Mypetlion
7

Folgendes musste ich in Python 3 arbeiten:

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()
Webucator
quelle
Hallo. Wie kann dieser Fehler vermieden werden : urllib.error.HTTPError: HTTP Error 302: The HTTP server returned a redirect error that would lead to an infinite loop.?
Victor M Herasme Perez
@ VictorHerasmePerez, ein HTTP 302-Antwortstatuscode bedeutet, dass die Seite verschoben wurde. Ich denke, das Problem, mit dem Sie konfrontiert sind, wird hier angesprochen: stackoverflow.com/questions/32569934/…
Webucator
5

Verwenden Sie entweder urllib2.urlopen, oder versuchen Sie, das hervorragende RequestsModul zu verwenden, und vermeiden Sie urllib2-Kopfschmerzen:

import requests
results = requests.get('url')
#pass results.content onto secondary processing...
Aravenel
quelle
1
Aber wie analysiert man die Ergebnisse. Inhalt in einer Zip?
0atman
Verwenden Sie das zipfileModul : zip = zipfile.ZipFile(results.content). Dann analysieren nur durch die Dateien mit ZipFile.namelist(), ZipFile.open()oderZipFile.extractall()
aravenel
5

Ich bin hierher gekommen, um zu suchen, wie man eine .bzip2-Datei speichert. Lassen Sie mich den Code für andere einfügen, die danach suchen könnten.

url = "http://api.mywebsite.com"
filename = "swateek.tar.gz"

response = requests.get(url, headers=headers, auth=('myusername', 'mypassword'), timeout=50)
if response.status_code == 200:
with open(filename, 'wb') as f:
   f.write(response.content)

Ich wollte die Datei nur so speichern, wie sie ist.

Swateek
quelle
3

Dank @yoavram für die oben genannte Lösung ist mein URL-Pfad mit einem komprimierten Ordner verknüpft und es tritt ein Fehler von BADZipfile auf (Datei ist keine Zip-Datei). Es war seltsam, wenn ich mehrmals versuchte, die URL abzurufen und alles zu entpacken plötzlich ändere ich die lösung ein wenig. mit dem is_zipfile Verfahren gemäß hier

r = requests.get(url, stream =True)
check = zipfile.is_zipfile(io.BytesIO(r.content))
while not check:
    r = requests.get(url, stream =True)
    check = zipfile.is_zipfile(io.BytesIO(r.content))
else:
    z = zipfile.ZipFile(io.BytesIO(r.content))
    z.extractall()
Hindamosh
quelle