requests - urllib python 3
Python equivalente de un comando wget dado (6)
Déjame mejorar un ejemplo con hilos en caso de que quieras descargar muchos archivos.
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()
Estoy tratando de crear una función de Python que hace lo mismo que este comando wget:
wget -c --read-timeout=5 --tries=0 "$URL"
-c
- Continúa desde donde lo dejaste si se interrumpe la descarga.
--read-timeout=5
- Si no se --read-timeout=5
datos nuevos durante más de 5 segundos, abandone y vuelva a intentarlo. Dado -c
esto significa que intentará nuevamente desde donde se detuvo.
--tries=0
- Reintentar por siempre.
Esos tres argumentos utilizados en tándem dan como resultado una descarga que no puede fallar.
Quiero duplicar esas características en mi script de Python, pero no sé por dónde empezar ...
También hay un buen módulo de Python llamado wget
que es bastante fácil de usar. Encontrado here
Esto demuestra la simplicidad del diseño:
>>> import wget
>>> url = ''http://www.futurecrew.com/skaven/song_files/mp3/razorback.mp3''
>>> filename = wget.download(url)
100% [................................................] 3841532 / 3841532>
>> filename
''razorback.mp3''
Disfrutar.
Sin embargo, si wget
no funciona (he tenido problemas con ciertos archivos PDF), pruebe esta solución .
Editar: También puede usar el parámetro out
para usar un directorio de salida personalizado en lugar del directorio de trabajo actual.
>>> output_directory = <directory_name>
>>> filename = wget.download(url, out=output_directory)
>>> filename
''razorback.mp3''
Tuve que hacer algo como esto en una versión de Linux que no tenía las opciones correctas compiladas en wget. Este ejemplo es para descargar la herramienta de análisis de memoria ''guppy''. No estoy seguro de si es importante o no, pero mantuve el nombre del archivo de destino igual que el nombre de destino de URL ...
Esto es lo que se me ocurrió:
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)"
Esa es la de una sola línea, aquí está un poco más legible:
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)
Esto funcionó para descargar un tarball. Pude extraer el paquete y descargarlo después de descargarlo.
EDITAR:
Para abordar una pregunta, aquí hay una implementación con una barra de progreso impresa en STDOUT. Probablemente haya una forma más portátil de hacerlo sin el paquete clint
, pero esto se probó en mi máquina y funciona 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()
fácil como 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
urllib.request debería funcionar. Simplemente configúrelo en un bucle de tiempo (no hecho), verifique si ya existe un archivo local, si envía un GET con un encabezado de RANGO, especificando hasta qué punto llegó la descarga del archivo local. Asegúrese de usar read () para adjuntar al archivo local hasta que se produzca un error.
Esto también es potencialmente un duplicado de la descarga del currículum de Python urllib2 no funciona cuando la red se vuelve a conectar
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)