Grundlegendes Herunterladen und Speichern von http-Dateien auf die Festplatte in Python?

159

Ich bin neu in Python und habe die Fragen und Antworten auf dieser Website durchgesehen, um eine Antwort auf meine Frage zu erhalten. Ich bin jedoch ein Anfänger und finde es schwierig, einige der Lösungen zu verstehen. Ich brauche eine sehr einfache Lösung.

Könnte mir bitte jemand eine einfache Lösung für das Herunterladen einer Datei über http und das Speichern auf einer Festplatte unter Windows erklären?

Ich bin mir auch nicht sicher, wie ich Shutil- und OS-Module verwenden soll.

Die Datei, die ich herunterladen möchte, hat eine Größe von weniger als 500 MB und ist eine .gz-Archivdatei. Wenn jemand erklären kann, wie das Archiv extrahiert und die darin enthaltenen Dateien auch verwendet werden, wäre das großartig!

Hier ist eine Teillösung, die ich aus verschiedenen Antworten zusammen geschrieben habe:

import requests
import os
import shutil

global dump

def download_file():
    global dump
    url = "http://randomsite.com/file.gz"
    file = requests.get(url, stream=True)
    dump = file.raw

def save_file():
    global dump
    location = os.path.abspath("D:\folder\file.gz")
    with open("file.gz", 'wb') as location:
        shutil.copyfileobj(dump, location)
    del dump

Könnte jemand auf Fehler hinweisen (Anfängerlevel) und einfachere Methoden erklären, um dies zu tun?

Vielen Dank!

Arvindch
quelle

Antworten:

206

Eine saubere Methode zum Herunterladen einer Datei ist:

import urllib

testfile = urllib.URLopener()
testfile.retrieve("http://randomsite.com/file.gz", "file.gz")

Dadurch wird eine Datei von einer Website heruntergeladen und benannt file.gz. Dies ist eine meiner Lieblingslösungen, vom Herunterladen eines Bildes über Urllib und Python .

In diesem Beispiel wird die urllibBibliothek verwendet, und die Datei wird direkt aus einer Quelle abgerufen.

Blaues Eis
quelle
3
OK danke! Aber gibt es eine Möglichkeit, es durch Anfragen zum Laufen zu bringen?
Arvindch
5
Gibt es eine Möglichkeit, in /myfolder/file.gz zu speichern?
John Snow
17
Keine bessere Möglichkeit, als es vielleicht selbst zu versuchen? :) Ich könnte es erfolgreich machen testfile.retrieve("http://example.com/example.rpm", "/tmp/test.rpm").
Dharmit
18
Dies ist seit Python 3.3 veraltet, und die Lösung urllib.request.urlretrieve (siehe Antwort unten) ist der "moderne" Weg
MichielB
1
Was ist der beste Weg, um diesem Code einen Benutzernamen und ein Passwort hinzuzufügen? tks
Estefy
109

Wie hier erwähnt :

import urllib
urllib.urlretrieve ("http://randomsite.com/file.gz", "file.gz")

EDIT:Wenn Sie immer noch Anfragen verwenden möchten, werfen Sie einen Blick auf diese Frage oder dieser ein .

dparpyani
quelle
1
urllib wird funktionieren, jedoch scheinen viele Leute die Verwendung von Anfragen über urllib zu empfehlen. Warum ist das?
Arvindch
2
requestsist im Vergleich zur urllibArbeit mit einer REST-API äußerst hilfreich . Wenn Sie nicht viel mehr tun möchten, sollte dies gut sein.
Dparpyani
Ok, jetzt habe ich die Links gelesen, die Sie für die Verwendung von Anfragen bereitgestellt haben. Ich bin verwirrt darüber, wie der Dateipfad zum Speichern des Downloads deklariert werden soll. Wie benutze ich OS und Shutil dafür?
Arvindch
62
Für Python3:import urllib.request urllib.request.urlretrieve(url, filename)
Flash
1
Ich kann den http-Statuscode damit nicht extrahieren, wenn der Download fehlschlägt
Aashish Thite
34

Ich benutze wget .

Einfache und gute Bibliothek, wenn Sie ein Beispiel geben möchten?

import wget

file_url = 'http://johndoe.com/download.zip'

file_name = wget.download(file_url)

Das Wget-Modul unterstützt die Versionen Python 2 und Python 3

Ali
quelle
33

Vier Methoden mit wget, urllib und request.

#!/usr/bin/python
import requests
from StringIO import StringIO
from PIL import Image
import profile as profile
import urllib
import wget


url = 'https://tinypng.com/images/social/website.jpg'

def testRequest():
    image_name = 'test1.jpg'
    r = requests.get(url, stream=True)
    with open(image_name, 'wb') as f:
        for chunk in r.iter_content():
            f.write(chunk)

def testRequest2():
    image_name = 'test2.jpg'
    r = requests.get(url)
    i = Image.open(StringIO(r.content))
    i.save(image_name)

def testUrllib():
    image_name = 'test3.jpg'
    testfile = urllib.URLopener()
    testfile.retrieve(url, image_name)

def testwget():
    image_name = 'test4.jpg'
    wget.download(url, image_name)

if __name__ == '__main__':
    profile.run('testRequest()')
    profile.run('testRequest2()')
    profile.run('testUrllib()')
    profile.run('testwget()')

testRequest - 4469882 Funktionsaufrufe (4469842 primitive Aufrufe) in 20,236 Sekunden

testRequest2 - 8580 Funktionsaufrufe (8574 primitive Aufrufe) in 0,072 Sekunden

testUrllib - 3810 Funktionsaufrufe (3775 primitive Aufrufe) in 0,036 Sekunden

testwget - 3489 Funktionsaufrufe in 0,020 Sekunden

Saurabh yadav
quelle
1
Wie haben Sie die Anzahl der Funktionsaufrufe erhalten?
Abdelhak
28

Für Python3 + URLopener ist veraltet. Und wenn verwendet, erhalten Sie Fehler wie folgt:

url_opener = urllib.URLopener () AttributeError: Modul 'urllib' hat kein Attribut 'URLopener'

Also versuche:

import urllib.request 
urllib.request.urlretrieve(url, filename)
Om Sao
quelle
1
Seltsam ... Warum niemand für diese Antwort stimmt, als Python 2 veraltet ist und nur diese Lösung richtig funktionieren sollte ...
wowkin2
1
Einverstanden! Ich zog meine Haare über die früheren Lösungen. Ich wünschte, ich könnte 200 Mal upvoten!
Yechiel K
5

Exotische Windows-Lösung

import subprocess

subprocess.run("powershell Invoke-WebRequest {} -OutFile {}".format(your_url, filename), shell=True)
Max
quelle
1

Ich habe diesen Weg eingeschlagen, weil ESXis Wget nicht mit SSL kompiliert ist und ich eine OVA von der Website eines Anbieters direkt auf den ESXi-Host herunterladen wollte, der sich auf der anderen Seite der Welt befindet.

Ich musste die Firewall deaktivieren (faul) / https out aktivieren, indem ich die Regeln bearbeitete (richtig)

hat das Python-Skript erstellt:

import ssl
import shutil
import tempfile
import urllib.request
context = ssl._create_unverified_context()

dlurl='https://somesite/path/whatever'
with urllib.request.urlopen(durl, context=context) as response:
    with open("file.ova", 'wb') as tmp_file:
        shutil.copyfileobj(response, tmp_file)

ESXi-Bibliotheken sind irgendwie gepaart, aber das Open-Source-Wiesel-Installationsprogramm schien urllib für https zu verwenden ... also hat es mich dazu inspiriert, diesen Weg zu gehen

Jayme Snyder
quelle
-5

Eine andere saubere Möglichkeit, die Datei zu speichern, ist folgende:

import csv
import urllib

urllib.retrieve("your url goes here" , "output.csv")
Ala
quelle
Dies sollte wahrscheinlich urllib.urlretrieveoder urllib.URLopener().retrieveunklar sein, was Sie hier gemeint haben.
Mateor
9
Warum importieren Sie CSV, wenn Sie nur eine Datei benennen?
Azeezah M