it-swarm.com.de

Python-Äquivalent eines gegebenen Wget-Befehls

Ich versuche, eine Python-Funktion zu erstellen, die dasselbe wie dieser wget-Befehl ausführt:

wget -c --read-timeout=5 --tries=0 "$URL"

-c - Fahren Sie an der Stelle fort, an der Sie aufgehört haben, wenn der Download unterbrochen wird.

--read-timeout=5 - Wenn nach mehr als 5 Sekunden keine neuen Daten eingehen, geben Sie auf und versuchen Sie es erneut. Bei -c bedeutet dies, dass es erneut versucht wird, wo er aufgehört hat.

--tries=0 - Immer wiederholen.

Diese drei im Tandem verwendeten Argumente führen zu einem Download, der nicht fehlschlagen kann.

Ich möchte diese Features in meinem Python-Skript kopieren, weiß aber nicht, wo ich anfangen soll ...

39
Soviero

urllib.request sollte funktionieren. Richten Sie es einfach in einer while-Schleife ein (nicht abgeschlossen), prüfen Sie, ob bereits eine localfile vorhanden ist, ob ein GET mit einem RANGE-Header gesendet wird, und geben Sie an, wie weit Sie beim Download der localfile gelangt sind. Verwenden Sie read (), um an die lokale Datei anzuhängen, bis ein Fehler auftritt.

Dies ist möglicherweise auch ein Duplikat von Download von Python urllib2 resume funktioniert nicht, wenn das Netzwerk sich wieder verbindet

21
Eugene K

Es gibt auch ein Nice Python-Modul mit dem Namen wget, das ziemlich einfach zu bedienen ist. Gefunden hier .

Dies zeigt die Einfachheit des Designs:

>>> import wget
>>> url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3'
>>> filename = wget.download(url)
100% [................................................] 3841532 / 3841532>
>> filename
'razorback.mp3'

Genießen.

Wenn jedoch wget nicht funktioniert (ich habe Probleme mit bestimmten PDF -Dateien), versuchen Sie diese Lösung .

Edit: Sie können den Parameter out auch verwenden, um ein benutzerdefiniertes Ausgabeverzeichnis anstelle des aktuellen Arbeitsverzeichnisses zu verwenden.

>>> output_directory = <directory_name>
>>> filename = wget.download(url, out=output_directory)
>>> filename
'razorback.mp3'
69
Blairg23
import urllib2

attempts = 0

while attempts < 3:
    try:
        response = urllib2.urlopen("http://example.com", timeout = 5)
        content = response.read()
        f = open( "local/index.html", 'w' )
        f.write( content )
        f.close()
        break
    except urllib2.URLError as e:
        attempts += 1
        print type(e)
13

Ich musste so etwas in einer Version von Linux tun, die nicht die richtigen Optionen in Wget kompilierte. In diesem Beispiel wird das Speicheranalyse-Tool 'guppy' heruntergeladen. Ich bin nicht sicher, ob es wichtig ist oder nicht, aber ich habe den Namen der Zieldatei genauso wie den Zielnamen der URL beibehalten ...

Folgendes habe ich mir ausgedacht:

python -c "import requests; r = requests.get('https://pypi.python.org/packages/source/g/guppy/guppy-0.1.10.tar.gz') ; open('guppy-0.1.10.tar.gz' , 'wb').write(r.content)"

Das ist der One-Liner, hier ist es etwas lesbarer:

import requests
fname = 'guppy-0.1.10.tar.gz'
url = 'https://pypi.python.org/packages/source/g/guppy/' + fname
r = requests.get(url)
open(fname , 'wb').write(r.content)

Dies funktionierte für das Herunterladen eines Archivs. Ich konnte das Paket extrahieren und nach dem Download herunterladen.

BEARBEITEN:

Um eine Frage zu beantworten, hier eine Implementierung mit einem Fortschrittsbalken, der an STDOUT gedruckt wird. Es gibt wahrscheinlich einen tragbareren Weg, dies ohne das Paket clint zu tun, aber dies wurde auf meinem Computer getestet und funktioniert gut:

#!/usr/bin/env python

from clint.textui import progress
import requests

fname = 'guppy-0.1.10.tar.gz'
url = 'https://pypi.python.org/packages/source/g/guppy/' + fname

r = requests.get(url, stream=True)
with open(fname, 'wb') as f:
    total_length = int(r.headers.get('content-length'))
    for chunk in progress.bar(r.iter_content(chunk_size=1024), expected_size=(total_length/1024) + 1): 
        if chunk:
            f.write(chunk)
            f.flush()
7
Will Charlton

einfach wie py:

class Downloder():
    def download_manager(self, url, destination='Files/DownloderApp/', try_number="10", time_out="60"):
        #threading.Thread(target=self._wget_dl, args=(url, destination, try_number, time_out, log_file)).start()
        if self._wget_dl(url, destination, try_number, time_out, log_file) == 0:
            return True
        else:
            return False


    def _wget_dl(self,url, destination, try_number, time_out):
        import subprocess
        command=["wget", "-c", "-P", destination, "-t", try_number, "-T", time_out , url]
        try:
            download_state=subprocess.call(command)
        except Exception as e:
            print(e)
        #if download_state==0 => successfull download
        return download_state
2
pd shah

Lassen Sie mich ein Beispiel mit Threads verbessern, falls Sie viele Dateien herunterladen möchten.

import math
import random
import threading

import requests
from clint.textui import progress

# You must define a proxy list
# I suggests https://free-proxy-list.net/
proxies = {
    0: {'http': 'http://34.208.47.183:80'},
    1: {'http': 'http://40.69.191.149:3128'},
    2: {'http': 'http://104.154.205.214:1080'},
    3: {'http': 'http://52.11.190.64:3128'}
}


# you must define the list for files do you want download
videos = [
    "https://i.stack.imgur.com/g2BHi.jpg",
    "https://i.stack.imgur.com/NURaP.jpg"
]

downloaderses = list()


def downloaders(video, selected_proxy):
    print("Downloading file named {} by proxy {}...".format(video, selected_proxy))
    r = requests.get(video, stream=True, proxies=selected_proxy)
    nombre_video = video.split("/")[3]
    with open(nombre_video, 'wb') as f:
        total_length = int(r.headers.get('content-length'))
        for chunk in progress.bar(r.iter_content(chunk_size=1024), expected_size=(total_length / 1024) + 1):
            if chunk:
                f.write(chunk)
                f.flush()


for video in videos:
    selected_proxy = proxies[math.floor(random.random() * len(proxies))]
    t = threading.Thread(target=downloaders, args=(video, selected_proxy))
    downloaderses.append(t)

for _downloaders in downloaderses:
    _downloaders.start()
0
Te ENe Te

Eine Lösung, die ich oft einfacher und robuster finde, ist die einfache Ausführung eines Terminalbefehls in Python. In Ihrem Fall:

import os
url = 'https://www.someurl.com'
os.system(f"""wget -c --read-timeout=5 --tries=0 "{url}"""")
0
Yohan Obadia