1148 Stimmen

Wie kann ich eine Datei über HTTP herunterladen?

Ich habe ein kleines Dienstprogramm, mit dem ich eine MP3-Datei nach einem bestimmten Zeitplan von einer Website herunterlade und dann eine Podcast-XML-Datei erstelle/aktualisiere, die ich zu iTunes hinzugefügt habe.

Die Textverarbeitung zur Erstellung/Aktualisierung der XML-Datei ist in Python geschrieben. Ich verwende jedoch wget innerhalb eines Windows .bat Datei, um die eigentliche MP3-Datei herunterzuladen. Ich würde es vorziehen, das gesamte Dienstprogramm in Python zu schreiben.

Ich hatte Mühe, eine Möglichkeit zu finden, die Datei in Python herunterzuladen, weshalb ich mich auf die Verwendung von wget .

Wie lade ich also die Datei mit Python herunter?

2 Stimmen

Viele der nachstehenden Antworten sind kein zufriedenstellender Ersatz für wget . Unter anderem, wget (1) bewahrt Zeitstempel (2) bestimmt automatisch den Dateinamen aus der URL und fügt ihn an .1 (usw.), wenn die Datei bereits existiert (3) hat viele andere Optionen, von denen Sie einige vielleicht in Ihrem .wgetrc . Wenn Sie etwas davon wollen, müssen Sie es selbst in Python implementieren, aber es ist einfacher, einfach die wget aus Python.

3 Stimmen

Kurze Lösung für Python 3: import urllib.request; s = urllib.request.urlopen('http://example.com/').read().decode(‌​)

1367voto

PabloG Punkte 24135

Eine weitere, die urlretrieve :

import urllib.request
urllib.request.urlretrieve("http://www.example.com/songs/mp3.mp3", "mp3.mp3")

(für Python 2 verwenden Sie import urllib y urllib.urlretrieve )

Ein weiteres Beispiel mit einem "Fortschrittsbalken".

import urllib2

url = "http://download.thinkbroadband.com/10MB.zip"

file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size)

file_size_dl = 0
block_sz = 8192
while True:
    buffer = u.read(block_sz)
    if not buffer:
        break

    file_size_dl += len(buffer)
    f.write(buffer)
    status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
    status = status + chr(8)*(len(status)+1)
    print status,

f.close()

1 Stimmen

Merkwürdigerweise funktionierte dies bei mir unter Windows, während die urllib2-Methode nicht funktionierte. Die urllib2-Methode funktionierte jedoch auf dem Mac.

7 Stimmen

Fehler: file_size_dl += block_sz sollte += len(buffer) sein, da das letzte Lesen oft nicht eine volle block_sz ist. Außerdem muss man unter Windows die Ausgabedatei als "wb" öffnen, wenn es sich nicht um eine Textdatei handelt.

1 Stimmen

Bei mir haben auch urllib und urllib2 nicht funktioniert, aber urlretrieve hat gut funktioniert, ich war schon frustriert - danke :)

561voto

Corey Punkte 13790

Utilisez urllib.request.urlopen() :

import urllib.request
with urllib.request.urlopen('http://www.example.com/') as f:
    html = f.read().decode('utf-8')

Dies ist die einfachste Art, die Bibliothek zu verwenden, ohne jegliche Fehlerbehandlung. Sie können auch komplexere Dinge wie das Ändern von Kopfzeilen tun.

Unter Python 2 befindet sich die Methode in urllib2 :

import urllib2
response = urllib2.urlopen('http://www.example.com/')
html = response.read()

13 Stimmen

Dies wird nicht funktionieren, wenn die von Ihnen angegebene URL Leerzeichen enthält. In diesem Fall müssen Sie die URL parsen und den Pfad urlencodieren.

115 Stimmen

Hier ist die Lösung in Python 3: stackoverflow.com/questions/7243750/

7 Stimmen

Nur zur Information. Die Art und Weise, wie der Pfad urlencodiert wird, ist urllib2.quote

422voto

hughdbrown Punkte 45214

Verwenden Sie im Jahr 2012 die python anfragen bibliothek

>>> import requests
>>> 
>>> url = "http://download.thinkbroadband.com/10MB.zip"
>>> r = requests.get(url)
>>> print len(r.content)
10485760

Sie können pip install requests um es zu bekommen.

Requests hat viele Vorteile gegenüber den Alternativen, da die API viel einfacher ist. Dies gilt insbesondere, wenn Sie eine Authentifizierung vornehmen müssen. urllib und urllib2 sind in diesem Fall ziemlich unintuitiv und mühsam.


2015-12-30

Der Fortschrittsbalken wird bewundert. Das ist cool, klar. Es gibt inzwischen mehrere Standardlösungen, darunter tqdm :

from tqdm import tqdm
import requests

url = "http://download.thinkbroadband.com/10MB.zip"
response = requests.get(url, stream=True)

with open("10MB", "wb") as handle:
    for data in tqdm(response.iter_content()):
        handle.write(data)

Dies ist im Wesentlichen die Umsetzung, die @kvance vor 30 Monaten beschrieben hat.

0 Stimmen

Wie speichere oder entpacke ich, wenn die Zip-Datei eigentlich ein Ordner mit vielen Dateien ist?

8 Stimmen

Wie geht das mit großen Dateien um, wird alles im Speicher abgelegt oder kann das in eine Datei geschrieben werden, ohne dass viel Speicherplatz benötigt wird?

9 Stimmen

Es ist möglich, große Dateien zu streamen, indem man stream=True in der Anfrage setzt. Sie können dann iter_content() für die Antwort aufrufen, um jeweils ein Stückchen zu lesen.

171voto

Grant Punkte 11649
import urllib2
mp3file = urllib2.urlopen("http://www.example.com/songs/mp3.mp3")
with open('test.mp3','wb') as output:
  output.write(mp3file.read())

Le site wb en open('test.mp3','wb') öffnet eine Datei (und löscht eine vorhandene Datei) im Binärmodus, so dass Sie damit Daten statt nur Text speichern können.

39 Stimmen

Der Nachteil dieser Lösung ist, dass die gesamte Datei in den Arbeitsspeicher geladen wird, bevor sie auf der Festplatte gespeichert wird, was bei großen Dateien auf einem kleinen System wie einem Router mit begrenztem Arbeitsspeicher zu bedenken ist.

2 Stimmen

@tripplet Wie könnten wir das also beheben?

11 Stimmen

Um das Lesen der gesamten Datei in den Speicher zu vermeiden, versuchen Sie, ein Argument an file.read das ist die Anzahl der zu lesenden Bytes. Siehe: gist.github.com/hughdbrown/c145b8385a2afa6570e2

163voto

bmaupin Punkte 12357

Python 3

  • urllib.request.urlopen

    import urllib.request
    response = urllib.request.urlopen('http://www.example.com/')
    html = response.read()
  • urllib.request.urlretrieve

    import urllib.request
    urllib.request.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')

    Nota: In der Dokumentation heißt es dazu, urllib.request.urlretrieve ist eine "veraltete Schnittstelle" und "könnte in Zukunft veraltet sein" (danke gerrit )

Python 2

  • urllib2.urlopen (Dank Corey )

    import urllib2
    response = urllib2.urlopen('http://www.example.com/')
    html = response.read()
  • urllib.urlretrieve (Dank PabloG )

    import urllib
    urllib.urlretrieve('http://www.example.com/songs/mp3.mp3', 'mp3.mp3')

3 Stimmen

Es hat sicher eine Weile gedauert, aber es ist endlich die einfache, unkomplizierte API, die ich von einer Python-Stdlib erwarte :)

0 Stimmen

Sehr schöne Antwort für python3, siehe auch docs.python.org/3/library/

0 Stimmen

@EdouardThiel Wenn Sie auf urllib.request.urlretrieve oben, dann werden Sie genau zu diesem Link weitergeleitet. Prost!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X