En esta guía, verás:
- Qué es
wget. - Por qué puede ser mejor que la biblioteca requests.
- Lo fácil que es usar
wgetcon Python. - Ventajas y desventajas de su adopción en scripts de Python.
¡Empecemos!
¿Qué es Wget?
wgetes una utilidad de línea de comandos para descargar archivos de la web utilizando HTTP, HTTPS, FTP, FTPS y otros protocolos de Internet. Está instalado de forma nativa en la mayoría de los sistemas operativos tipo Unix, pero también está disponible para Windows.
¿Por qué Wget y no un paquete de Python como requests?
Sin duda, wget es una herramienta de línea de comandos muy interesante, pero ¿por qué deberías utilizarla para descargar archivos en Python en lugar de una biblioteca popular comorequests?
Bueno, hay una lista de razones de peso para usar wget en lugar de requests:
- Admite muchos más protocolos que requests.
- Puede reanudar descargas abortadas o interrumpidas.
- Admite la especificación de una velocidad de descarga limitada para que no consuma todo el ancho de banda de la red.
- Admite nombres de archivo y ubicaciones de red con comodines.
- Archivos de mensajes basados en NLS para muchos idiomas.
- Puede convertir enlaces absolutos en documentos descargados a enlaces relativos.
- Admiteproxies HTTP/S.
- Admite conexiones HTTP persistentes.
- Puede realizar operaciones de descarga desatendidas/en segundo plano.
- Utiliza marcas de tiempo de archivos locales para determinar si los documentos deben volver a descargarse al duplicarlos.
- Puede descargar de forma recursiva los archivos vinculados en una página web específica o hasta alcanzar una profundidad de recursividad especificada por el usuario.
- Respeta automáticamente las reglas de exclusión de robots definidas en robots.txt. Obtenga más información en nuestra guía sobrerobots.txt para el Scraping web.
Estas son solo algunas de las características de wget que lo hacen tan potente y especial en comparación con cualquier biblioteca cliente HTTP de Python. Descubra más en elmanual oficial.
En particular, ten en cuenta cómo wget puede seguir enlaces en páginas HTML y descargar archivos a los que se hace referencia en esas páginas. Eso te ayuda a recuperar incluso sitios web completos, lo que hace que wget sea ideal parael rastreo web.
En resumen, wget es una gran opción a la hora de escribir scripts que necesitan descargar archivos y páginas web. ¡Aprendamos a usar wget con Python!
Ejecutar comandos CLI en Python
Sigue los pasos que se indican a continuación y crea un script de Python que pueda ejecutar comandos wget.
Requisitos previos
Antes de empezar, asegúrate de tener wget instalado en tu ordenador. El proceso de configuración varía en función de tu sistema operativo:
- En Linux, ya debería tenerlo preinstalado. De lo contrario, instálelo utilizando el gestor de paquetes de su distribución.
- En Mac,instale
wgetcon Homebrew. - En Windows, descargueel binario
de Wgetpara Windowsy colóquelo en una carpeta. A continuación, añada la ruta del binariode wget(por ejemplo, C:Program Files (x86)Wget) a suvariable de entorno PATH.
También necesitarás tener instalado Python 3+ en tu máquina. Para configurarlo,descarga el instalador, haz doble clic en él y sigue las instrucciones.
Tambiénte resultaráútil un IDE de Python, comoPyCharm Community EditionoVisual Studio Code con la extensión Python.
Configurar un proyecto Python
Cree un proyecto Python wget con unentorno virtualutilizando los siguientes comandos:
mkdir wget-python-demo
cd wget-python-demo
python -m venv env
El directorio wget-python-demo creado anteriormente representa la carpeta de su proyecto.
Cárguelo en su IDE de Python, cree un archivo script.py e inicialícelo de la siguiente manera:
print('Hello, World!')
Por ahora, se trata solo de un script de ejemplo que imprime «¡Hola, mundo!» en la terminal. Pronto, contendrá la lógica de integración de wget.
Comprueba que el script funciona pulsando el botón de ejecución de tu IDE o con el siguiente comando:
python script.py
En la terminal, debería ver:
¡Hola, mundo!
¡Perfecto! Ahora ya tienes un proyecto Python en marcha.
¡Vea cómo usar wget en la siguiente sección!
Escribe una función para ejecutar comandos CLI a través del módulo subprocess
La forma más fácil de ejecutar comandos CLI en un script de Python es utilizando el módulosubprocess.
Esta biblioteca de la biblioteca estándar de Python te permite generar nuevos procesos, conectarte a sus tuberías de entrada/salida/error y obtener su código de retorno. En otras palabras, te proporciona todo lo que necesitas para ejecutar comandos en la terminal desde Python.
Así es como puedes utilizar el métodoPopen()de subprocess para ejecutar comandos CLI como wget con Python:
import subprocess
def execute_command(command):
"""
Ejecuta un comando CLI y devuelve los mensajes de salida y error.
Parámetros:
- command (str): El comando CLI a ejecutar.
Devuelve:
- output (str): La salida generada por el comando.
- error (str): El mensaje de error generado por el comando, si lo hay.
"""
try:
# ejecuta el comando y captura los mensajes de salida y de error
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
salida, error = proceso.communicate()
salida = salida.decode("utf-8")
error = error.decode("utf-8")
# devuelve la salida y los mensajes de error
devuelve salida, error
except Exception as e:
# si se produce una excepción, devuelve el mensaje de excepción como un error
devuelve None, str(e)
Popen() ejecuta el comando que pasaste como cadena en un nuevo proceso en tu sistema operativo. La opción shell=True garantiza que el método utilizará el shell predeterminado configurado en tu sistema operativo.
Pega el fragmento anterior en tu archivo script.py. Ahora puedes invocar un comando CLI en Python como en el siguiente ejemplo:
salida, error = ejecutar_comando("<cadena de comando CLI>")
if error:
imprimir("Se produjo un error al ejecutar el comando CLI:", error)
else:
imprimir("Salida del comando CLI:", salida)
Uso de Wget con Python: casos de uso
Esta es la sintaxis de un comando wget:
wget [opciones] [url]
Donde:
- [opciones] es una lista de las opciones y banderas compatibles con la herramienta CLI para personalizar su comportamiento.
- url es la URL del archivo que desea descargar. Puede ser un enlace directo a un archivo o la URL de una página web que contenga enlaces a varios archivos.
Nota: En Windows, escriba wget.exe en lugar de wget.
¡Es hora de ver wget en acción en algunos fragmentos de Python que cubren casos de uso populares!
Descargar un archivo
Supongamos que desea descargar http://lumtest.com/myip.json con wget. El comando para hacerlo sería:
wget http://lumtest.com/myip.json
En Python, eso se convertiría en la siguiente línea de código:
output, error = execute_command("wget http://lumtest.com/myip.json")
Si imprimes output, verás algo como:
--2024-04-18 15:20:59-- http://lumtest.com/myip.json
Resolviendo lumtest.com (lumtest.com)... 3.94.72.89, 3.94.40.55
Conectando con lumtest.com (lumtest.com)|3.94.72.89|:80... conectado.
Solicitud HTTP enviada, esperando respuesta... 200 OK
Longitud: 266 [application/json]
Guardando en: 'myip.json.1'
myip.json.1 100 %[=================================================>] 266 --.-KB/s en 0 s
18/04/2024 15:20:59 (5,41 MB/s) - 'myip.json.1' guardado [266/266]
En el resultado del comando, se puede ver que:
- La URL se resuelve a la dirección IP del servidor.
wgetse conecta al servidor mediante una solicitud HTTP al recurso especificado.- El código de estado de la respuesta HTTP recibido por el servidor es 200.
wgetdescarga el archivo y lo almacena en el directorio actual.
El directorio de su proyecto Python ahora contendrá un archivo myip.json.
Si desea cambiar la carpeta de destino donde almacenar el archivo que se va a descargar, utilice el indicador –directory-prefix o -P como se muestra a continuación:
salida, error = execute_command("wget --directory-prefix=./download http://lumtest.com/myip.json")
El archivo myip.json se almacenará ahora en la carpeta de descargas dentro del directorio de su proyecto. Tenga en cuenta que si la carpeta de destino no existe, wget la creará automáticamente.
Para cambiar el nombre del archivo del recurso descargado, utilice el indicador –output-document o -O:
salida, error = ejecutar_comando("wget --output-document=nombre-personalizado.json http://lumtest.com/myip.json")
Esta vez, el script Python wget creará un archivo llamado custom-name.json en lugar de myip.json.
Descargar una página web
El comando wget es el mismo que antes, con la diferencia principal de que esta vez url apuntará a una página web:
salida, error = ejecutar_comando("wget https://brightdata.com/")
El directorio de su proyecto ahora contendrá un archivo index.html con el contenido HTML de la página web https://brightdata.com/.
Descargar un archivo solo si ha cambiado desde la última descarga
Para ahorrar espacio en disco y recursos de red, es posible que no desee descargar un archivo si no ha cambiado desde la última descarga. Por eso wget ofrecefunciones de marca de tiempo de archivos.
En concreto, la opción –timestamping indica a wget que compare las marcas de tiempo de los archivos locales con las del servidor. Si el archivo local tiene una marca de tiempo igual o posterior a la del servidor, wget no volverá a descargar el archivo. De lo contrario, lo descargará.
Así es como funciona el mecanismo de marca de tiempo:
- Cuando descargas un archivo utilizando la opción –timestamping o -N,
wgetrecupera la marca de tiempo del archivo remoto. - Comprueba la marca de tiempo del archivo local (si existe) y la compara con la marca de tiempo del archivo remoto.
- Si el archivo local no existe o si su marca de tiempo es anterior a la del servidor,
wgetdescarga el archivo. Si el archivo local existe y su marca de tiempo es igual o posterior a la del servidor,wgetno descargará el archivo.
La marca de tiempo en HTTP se implementa comprobando el encabezadoLast-Modifieddevuelto por el servidor después de una solicitud HEAD. wget también mirará el encabezadoContent-Lengthpara comparar los tamaños de los archivos. Si no son iguales, el archivo remoto se descargará independientemente de lo que diga el encabezado Last-Modified. Tenga en cuenta que Last-Modified es un encabezado de respuesta opcional. Si no está presente, wget descargará el archivo de todos modos.
Utilice la opción –timestamping en Python con la siguiente línea de código:
salida, error = execute_command("wget --timestamping https://brightdata.com")
Si ya ha descargado index.hml, aparecerá el siguiente mensaje indicando que el archivo no se volverá a descargar:
--2024-04-18 15:55:06-- https://brightdata.com
Resolviendo brightdata.com (brightdata.com)... 104.18.25.60, 104.18.24.60
Conectando con brightdata.com (brightdata.com)|104.18.25.60|:443... conectado.
Solicitud HTTP enviada, esperando respuesta... 304 No modificado
El archivo «index.html» no se ha modificado en el servidor. Se omite la descarga.
El mismo mecanismo también funciona aldescargar archivos a través de FTP.
Completar descargas interrumpidas
De forma predeterminada, wget reintenta automáticamente la descarga de un archivo hasta 20 veces si se pierde la conexión durante el proceso. Si desea continuar manualmente con la descarga de un archivo parcialmente descargado, utilice la opción –continue o -c de la siguiente manera:
salida, error = execute_command("wget --continue http://lumtest.com/myip.json")
Descargar un sitio completo
La descarga recursiva es una función de wget que permite descargar un sitio completo con un solo comando.
A partir de la URL especificada, wget realiza el parseo de la página HTML y sigue los demás documentos que se encuentran en los atributos HTML src y href o en los atributos CSS url(). Si el siguiente archivo también es un archivo de texto/HTML, lo realizará y seguirá también sus documentos hasta alcanzar la profundidad deseada. La descarga recursiva sigue unalgoritmo de búsqueda en anchura, recuperando los archivos en profundidad 1, luego en profundidad 2, y así sucesivamente.
Las opciones de wget que hay que tener en cuenta al utilizar este modo de descarga son:
- –recursive o -r: Indica
a wgetque descargue los archivos de forma recursiva, lo que significa que seguirá los enlaces de las páginas web. Le permite crear copias locales de sitios web completos, incluidos todos los recursos vinculados, como imágenes, hojas de estilo, scripts, etc. Cuando se especifica esta opción,wgetalmacena todos los archivos descargados en una carpeta con el mismo nombre que el nombre de dominio del sitio de destino. - –level=<profundidad> o -l=<profundidad>: especifica la profundidad máxima de recursividad que se seguirá al descargar las páginas enlazadas. Por ejemplo, si se establece –level=1,
wgetsolo descargará las páginas enlazadas directamente desde la URL de inicio. No seguirá los enlaces de esas páginas para descargar otras páginas. Para evitar rastrear sitios enormes, el valor de profundidad predeterminado es 5. Establezca esta opción en 0 o «inf» para una profundidad infinita. Si desea asegurarse de que se descarguen todos los recursos necesarios para mostrar correctamente una página, independientemente de la profundidad especificada, añada la opción -p o –page-requisites. - –convert-links o -k: Modifica los enlaces de los archivos HTML descargados para que apunten a los archivos descargados localmente en lugar de a las URL originales. Esta opción es útil cuando se desea crear un espejo local de un sitio y asegurarse de que todos los enlaces de las páginas descargadas funcionan correctamente sin conexión.
Supongamos que desea descargar recursivamente el sitio Bright Data con una profundidad máxima de 1, al tiempo que convierte todos los enlaces para que apunten a archivos locales. Esta es la instrucción wget de Python que debe escribir:
output, error = execute_command("wget --recursive --level=1 --convert-links https://brightdata.com")
Nota: Este comando puede tardar un tiempo dependiendo de la velocidad de su conexión a Internet, así que tenga paciencia.
La carpeta brightdata.com contendrá ahora una copia local de los archivos del sitio Bright Data con un nivel de recursividad de 1.
Ventajas y desventajas de usar Wget con Python
Veamos las ventajas y desventajas de usar wget con Python.
Ventajas
- Fácil integración con Python gracias al módulo subprocess.
- Gran cantidad de funciones y opciones, incluyendo descarga recursiva, reintentos automáticos, sellado de archivos y mucho más.
- Puede hacer una copia local de todo un sitio con un solo comando.
- Compatibilidad con FTP.
- Compatibilidad con la integración de Proxy.
- Capacidad para recuperar descargas interrumpidas.
Contras
- El resultado son archivos descargados y no variables de cadena que se pueden utilizar directamente en el script de Python.
- Se necesita un analizador sintáctico comoBeautiful Souppara acceder a elementos DOM específicos de los archivos HTML descargados.
[Extra] Uso de Wget con un Proxy
El principal reto de utilizar wget para descargar un archivo o un sitio completo es que tus solicitudes pueden ser bloqueadas. Esto se debe a que las solicitudes de wget aparecerán en los servidores de destino como si procedieran de un bot. Para protegerse contra ellos, algunos sitios webimplementan restricciones y limitacionespara sus páginas y recursos. Estas limitaciones pueden incluir restricciones geográficas, políticas de limitación de velocidad o medidas anti-scraping.
Integrar unProxyen wget es una solución viable para eludir estas restricciones. Un Proxy actúa como un servidor intermedio entre el ordenador e Internet. Al reenviar el tráfico de wget a través de un Proxy, puedes evitar exponer tu IP y eludir la mayoría de las limitaciones impuestas por los sitios.
Para obtener un tutorial más completo, consulte nuestra guía sobrecómo utilizar un Proxy con Wget.
Conclusión
En este artículo, ha comprendido qué es wget, por qué puede ser mejor que la biblioteca requests y cómo utilizarlo en Python. Ahora sabe que wget es una potente herramienta para descargar archivos y páginas web a través de HTTP, HTTPS y FTP. Gracias a lo que ha aprendido aquí, sabe cómo utilizar wget con Python.
Como se ha visto en esta guía, un Proxy puede ser un gran aliado para evitar todas las medidas antibots que toman los sitios web para impedir que utilidades como wget descarguen su contenido. El problema es que hay docenas de proveedores en línea y elegir el mejor no es fácil. Ahorra tiempo y ve directamente al mejor del mercado,¡Bright Data!
Bright Data controla los mejores servidores Proxy del mundo, prestando servicio a empresas de la lista Fortune 500 y a más de 20 000 clientes. Su oferta incluye una amplia gama de tipos de Proxy:
- Proxy de centro de datos: más de 770 000 IP de centros de datos.
- Proxies residenciales: más de 72 millones de IPs residenciales en más de 195 países.
- ProxyISP: más de 700 000 IP de ISP.
- Proxy móvil: más de 7 millones de IP móviles.
Empiece con una prueba gratuita o hable con uno de nuestros expertos en datos sobre nuestras soluciones de Proxy y scraping.