Équivalent en Python d'une commande wget donnée
j'essaie de créer une fonction Python qui fait la même chose que cette commande wget:
wget -c --read-timeout=5 --tries=0 "$URL"
-c
- continuez à partir de l'endroit où vous vous êtes arrêté si le téléchargement est interrompu.
--read-timeout=5
- s'il n'y a pas de nouvelles données à venir pendant plus de 5 secondes, abandonner et essayer à nouveau. Étant donné -c
cela signifie qu'il va essayer de nouveau à partir de là où il s'est arrêté.
--tries=0
- pour toujours.
ces trois arguments utilisés en tandem aboutit à 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...
6 réponses
urllib.la demande devrait fonctionner. Il suffit de le configurer dans une boucle while(not done), vérifier si un fichier localfile existe déjà, s'il envoie un GET avec un en-tête RANGE, en spécifiant jusqu'où vous êtes arrivé à télécharger le fichier localfile. Assurez-vous d'utiliser read() pour ajouter à la localfile jusqu'à ce qu'une erreur se produit.
c'est aussi potentiellement un duplicata de Python urllib2 reprendre le téléchargement ne fonctionne pas lorsque le réseau se reconnecte
il y a aussi un joli module Python nommé wget
qui est assez facile à utiliser. Trouvé ici .
Cela démontre la simplicité de la conception:
>>> import wget
>>> url = 'http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3'
>>> filename = wget.download(url)
100% [................................................] 3841532 / 3841532>
>> filename
'razorback.mp3'
de Profiter de.
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 out
paramètre pour utiliser un répertoire de sortie personnalisé au lieu du répertoire de travail courant.
>>> output_directory = <directory_name>
>>> filename = wget.download(url, out=output_directory)
>>> filename
'razorback.mp3'
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)
j'ai dû faire quelque chose comme ça sur une version de linux qui n'avait pas les bonnes options compilées dans wget. Cet exemple est pour télécharger l'outil d'analyse de mémoire 'guppy'. Je ne suis pas sûr que ce soit important ou pas, mais j'ai gardé le nom du fichier cible le même que le nom de l'url cible...
voilà ce que j'ai trouvé:
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, 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)
This travaillé pour le téléchargement d'une archive. J'ai pu extraire le paquet et le télécharger après le téléchargement.
EDIT:
pour répondre à une question, voici une implémentation avec une barre de progression imprimée à STDOUT. Il y a probablement une façon plus portable de faire cela sans le paquet clint
, mais cela a été testé sur ma machine et fonctionne très 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()
facile 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
Permettez-moi D'améliorer un exemple avec des threads dans le cas où vous voulez télécharger de nombreux 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()