web-dev-qa-db-fra.com

Equivalent Python d'une commande wget donnée

J'essaie de créer une fonction Python qui fasse la même chose que cette commande wget:

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

-c - Continuez là où vous vous êtes arrêté si le téléchargement est interrompu.

--read-timeout=5 - Si aucune nouvelle donnée n'arrive pendant plus de 5 secondes, abandonnez et essayez à nouveau. Étant donné -c, cela signifie qu'il essaiera de nouveau là où il s'est arrêté.

--tries=0 - Réessayer pour toujours.

Ces trois arguments utilisés en tandem aboutissent à un téléchargement qui ne peut pas échouer.

Je veux dupliquer ces fonctionnalités dans mon script Python, mais je ne sais pas par où commencer ...

39
Soviero

urllib.request devrait fonctionner. Il suffit de le configurer dans une boucle while (not done), de vérifier s’il existe déjà un fichier local, s’il envoie un GET avec un en-tête RANGE, en précisant dans quelle mesure vous avez téléchargé le fichier local. Assurez-vous d'utiliser read () pour ajouter au fichier local jusqu'à ce qu'une erreur se produise.

C’est aussi potentiellement un doublon de Le téléchargement du CV Python urllib2 ne fonctionne pas lorsque le réseau se reconnecte

21
Eugene K

Il existe également un module Nice Python nommé wget qui est assez facile à utiliser. Trouvé ici .

Cela démontre la simplicité du design:

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

Prendre plaisir.

Cependant, si wget ne fonctionne pas (j'ai eu des problèmes avec certains fichiers PDF), essayez cette solution .

Edit: Vous pouvez également utiliser le paramètre out pour utiliser un répertoire de sortie personnalisé au lieu du répertoire de travail actuel.

>>> 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
Pujan Srivastava

Je devais faire quelque chose comme ça sur une version de Linux qui n'avait pas les bonnes options compilées dans wget. Cet exemple concerne le téléchargement de l'outil d'analyse de la mémoire 'guppy'. Je ne sais pas si c'est important ou non, mais j'ai conservé le nom du fichier cible identique à celui de l'URL ...

Voici ce que je suis venu avec:

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

C'est le one-liner, le voici un peu plus lisible:

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)

Cela a fonctionné pour télécharger une archive. J'ai pu extraire le package et le télécharger après le téléchargement.

MODIFIER:

Pour répondre à une question, voici une implémentation avec une barre de progression imprimée sur STDOUT. Il existe probablement un moyen plus portable de le faire sans le package clint, mais cela a été testé sur ma machine et fonctionne bien:

#!/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

facile comme 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

Permettez-moi d'améliorer un exemple avec des discussions au cas où vous voudriez télécharger plusieurs fichiers.

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

Une solution que je trouve souvent plus simple et plus robuste consiste simplement à exécuter une commande de terminal dans python. Dans ton cas:

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