Python-equivalent van een gegeven wget-commando

Ik probeer een Python-functie te maken die hetzelfde doet als dit wget-commando:

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

-c– Ga verder waar je was gebleven als de download wordt onderbroken.

--read-timeout=5– Als er langer dan 5 seconden geen nieuwe gegevens binnenkomen, geef het dan op en probeer het opnieuw. Gezien -cbetekent dit dat het het opnieuw zal proberen vanaf het punt waar het was gebleven.

--tries=0– Probeer het voor altijd opnieuw.

Deze drie argumenten die samen worden gebruikt, resulteren in een download die niet kan mislukken.

Ik wil die functies in mijn Python-script dupliceren, maar ik weet niet waar ik moet beginnen…


Antwoord 1, autoriteit 100%

urllib.requestzou moeten werken.
Stel het gewoon in een while(not done)-lus in, controleer of er al een localfile bestaat, als het een GET stuurt met een RANGE-header, specificeer hoe ver je bent gekomen met het downloaden van de localfile.
Zorg ervoor dat u read() gebruikt om toe te voegen aan het localfile totdat er een fout optreedt.

Dit is mogelijk ook een duplicaat van Python urllib2 CV-download werkt niet wanneer het netwerk opnieuw verbinding maakt


Antwoord 2, autoriteit 96%

Er is ook een mooie Python-module genaamd wgetdie vrij eenvoudig te gebruiken. Houd er rekening mee dat het pakket sinds 2015 niet is bijgewerkt en een aantal belangrijke functies niet heeft geïmplementeerd, dus het kan beter zijn om andere methoden te gebruiken. Het hangt helemaal af van je use-case. Voor eenvoudig downloaden is deze module het ticket. Als u meer moet doen, zijn er andere oplossingen.

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

Veel plezier.

Als wgetechter niet werkt (ik heb problemen gehad met bepaalde PDF-bestanden), probeer dan deze oplossing.

Bewerken:u kunt ook de parameter outgebruiken om een aangepaste uitvoermap te gebruiken in plaats van de huidige werkmap.

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

Antwoord 3, autoriteit 52%

import urllib2
import time
max_attempts = 80
attempts = 0
sleeptime = 10 #in seconds, no reason to continuously try if network is down
#while true: #Possibly Dangerous
while attempts < max_attempts:
    time.sleep(sleeptime)
    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)

Antwoord 4, autoriteit 48%

Ik moest zoiets doen op een versie van linux die niet de juiste opties had gecompileerd in wget. Dit voorbeeld is voor het downloaden van de geheugenanalysetool ‘guppy’. Ik weet niet zeker of het belangrijk is of niet, maar ik heb de naam van het doelbestand hetzelfde gehouden als de url-doelnaam…

Dit is wat ik heb bedacht:

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

Dat is de oneliner, hier is het een beetje leesbaarder:

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)

Dit werkte voor het downloaden van een tarball. Ik kon het pakket uitpakken en downloaden na het downloaden.

BEWERKEN:

Om een vraag te beantwoorden, hier is een implementatie met een voortgangsbalk afgedrukt naar STDOUT. Er is waarschijnlijk een meer draagbare manier om dit te doen zonder het clintpakket, maar dit is getest op mijn machine en werkt prima:

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

Antwoord 5, Autoriteit 45%

Een oplossing die ik vaak eenvoudiger en robuust vind, is eenvoudigweg een terminalopdracht binnen Python uit te voeren. In uw geval:

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

Antwoord 6, Autoriteit 35%

Voor Windows en Python 3.x , mijn twee centen bijdrage over Renaming van het bestand op download :

  1. installeren wget module: pip install wget
  2. Gebruik wget:
import wget
wget.download('Url', 'C:\\PathToMyDownloadFolder\\NewFileName.extension')

Truely Working Command Line Voorbeeld:

python -c "import wget; wget.download(""https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.17.2.tar.xz"", ""C:\\Users\\TestName.TestExtension"")"

OPMERKING : ‘C: \\ pathtomydownloadfolder \\ Newfilename.extension’ is niet verplicht. Standaard wordt het bestand niet hernoemd en de downloadmap is uw lokale pad.


Antwoord 7, Autoriteit 10%

Hier is de code die is aangenomen van de Torchvision Library :

import urllib
def download_url(url, root, filename=None):
    """Download a file from a url and place it in root.
    Args:
        url (str): URL to download file from
        root (str): Directory to place downloaded file in
        filename (str, optional): Name to save the file under. If None, use the basename of the URL
    """
    root = os.path.expanduser(root)
    if not filename:
        filename = os.path.basename(url)
    fpath = os.path.join(root, filename)
    os.makedirs(root, exist_ok=True)
    try:
        print('Downloading ' + url + ' to ' + fpath)
        urllib.request.urlretrieve(url, fpath)
    except (urllib.error.URLError, IOError) as e:
        if url[:5] == 'https':
            url = url.replace('https:', 'http:')
            print('Failed download. Trying https -> http instead.'
                    ' Downloading ' + url + ' to ' + fpath)
            urllib.request.urlretrieve(url, fpath)

Als het oké is om afhankelijk te zijn van de torchvision-bibliotheek, doe je ook gewoon:

from torchvision.datasets.utils import download_url
download_url('https://something.com/file.zip', '~/my_folder`)

Antwoord 8, autoriteit 2%

Laat me een voorbeeld verbeteren met threads voor het geval je veel bestanden wilt downloaden.

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

Antwoord 9, Autoriteit 2%

eenvoudig als 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

Antwoord 10

Tensorflow maakt het leven gemakkelijker. File Path geeft ons de locatie van gedownload bestand.

import tensorflow as tf
tf.keras.utils.get_file(origin='https://storage.googleapis.com/tf-datasets/titanic/train.csv',
                                    fname='train.csv',
                                    untar=False, extract=False)

Other episodes