Como usar o wget com Python para baixar páginas e arquivos da web

Este guia abrangente apresenta o wget, uma poderosa ferramenta de linha de comando para baixar arquivos via HTTP, HTTPS e FTP, comparando-o favoravelmente com a biblioteca requests em Python.
14 min read
Illustration of wget usage with Python

Neste tutorial, mostraremos:

  • O que é wget.
  • Por que ele pode ser melhor do que a biblioteca requests.
  • Como é fácil usar wget com Python.
  • Prós e contras de sua adoção nos scripts Python.

Vamos lá!

O que é o wget?

wget é um utilitário de linha de comando para baixar arquivos da web usando HTTP, HTTPS, FTP, FTPS e outros protocolos da internet. Ele é instalado nativamente na maioria dos sistemas operacionais semelhantes ao Unix, mas também está disponível para Windows.

Por que o wget e não um pacote Python como requests?

Claro, wget é uma ferramenta de linha de comando interessante, mas por que você deveria usá-la para baixar arquivos em Python em vez de uma biblioteca popular como requests?

Bem, há uma lista de razões convincentes para usar wget em vez de requests:

  • Suporta muito mais protocolos do que Requests.
  • Pode retomar downloads cancelados ou interrompidos.
  • Suporta a especificação de uma velocidade de download limitada para que não consuma toda a largura de banda da rede.
  • Suporta nomes de arquivos e locais de rede com curingas.
  • Arquivos de mensagens baseados em NLS para vários idiomas.
  • Pode converter links absolutos em documentos baixados em links relativos.
  • Suporta proxies HTTP/S.
  • Suporta conexões HTTP persistentes.
  • Pode realizar operações de download autônomo/em segundo plano.
  • Usa carimbos de data e hora do arquivo local para determinar se os documentos precisam ser baixados novamente durante o espelhamento.
  • Pode baixar recursivamente arquivos vinculados a uma página da web específica ou até atingir uma profundidade de recursão especificada pelo usuário.
  • Respeita automaticamente as regras de exclusão de robôs definidas em robots.txt. Saiba mais em nosso guia sobre robots.txt para extração de dados da web.

Esses são apenas alguns dos recursos do wget que o tornam tão poderoso e especial em comparação com qualquer biblioteca de cliente HTTP do Python. Descubra mais no manual oficial.

Em particular, observe como o wget pode seguir links em páginas HTML e baixar arquivos referenciados nessas páginas. Isso ajuda você a recuperar até mesmo sites inteiros, tornando o wget ideal para rastreamento da web.

Resumindo, o wget é uma ótima opção ao escrever scripts que precisam baixar arquivos e páginas da web. Vamos aprender como usar wget com Python!

Executando comandos CLI em Python

Siga as etapas abaixo e crie um script Python que possa executar comandos wget.

Pré-requisitos

Antes de começar, certifique-se de ter o wget instalado em sua máquina. O processo de configuração muda de acordo com seu sistema operacional:

  • No Linux, você já deve tê-lo pré-instalado. Caso contrário, instale-o usando o seu gerenciador de pacotes da distribuição.
  • No Mac, instale wget com o Homebrew.
  • No Windows, baixe o binário Wget para Windows e coloque-o em uma pasta. Em seguida, adicione o caminho binário wget (por exemplo, C:\Program Files (x86)\Wget) à sua variável de ambiente PATH.

Você também precisará do Python 3+ instalado em sua máquina. Para configurá-lo, baixe o instalador, clique duas vezes nele e siga as instruções.

Um IDE para Python como PyCharm Community Edition ou Visual Studio Code com a extensão Python também serão úteis.

Configurar um projeto Python

Crie um projeto Python wget com um ambiente virtual usando os comandos abaixo:

mkdir wget-python-demo

cd wget-python-demo

python -m venv env

O diretório wget-python-demo criado acima representa a pasta do seu projeto.

Abra-o no seu IDE para Python, crie um arquivo scraper.py e inicialize-o da seguinte forma:

print('Hello, World!')

No momento, este é apenas um exemplo de script que imprime “Olá, mundo!” no terminal. Em breve, ele conterá a lógica de integração wget.

Verifique se o script funciona pressionando o botão Run (executar) do seu IDE ou com o comando abaixo:

python script.py

No terminal, você deve ver:

Hello, World!

Perfeito! Agora você tem um projeto Python implementado.

Veja como usar wget na próxima seção!

Escreva uma função para executar comandos CLI por meio do módulo subprocess

A maneira mais fácil de executar comandos CLI em um script Python é usando o módulo subprocess .

Essa biblioteca da Biblioteca Padrão do Python permite que você gere novos processos, conecte-se aos seus canais de entrada/saída/erro e obtenha o código de retorno. Em outros termos, ele fornece tudo o que você precisa para executar comandos no terminal a partir de Python.

É assim que você pode usar o método Popen () do subprocess para executar comandos CLI como wget com Python:

import subprocess

def execute_command(command):

"""

Execute a CLI command and return the output and error messages.

Parameters:

- command (str): The CLI command to execute.

Returns:

- output (str): The output generated by the command.

- error (str): The error message generated by the command, if any.

"""

try:

# execute the command and capture the output and error messages

process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

output, error = process.communicate()

output = output.decode("utf-8")

error = error.decode("utf-8")

# return the output and error messages

return output, error

except Exception as e:

# if an exception occurs, return the exception message as an error

return None, str(e)

Popen () executa o comando que você passou como uma string em um novo processo no seu sistema operacional. A opção shell=True garante que o método use o shell padrão configurado no seu sistema operacional.

Cole o trecho acima no seu arquivo script.py. Agora você pode invocar um comando CLI em Python, como no exemplo a seguir:

output, error = execute_command("<CLI command string>")

if error:

print (“Ocorreu um erro ao executar o comando CLI:”, error)

else:

print (“Saída do comando CLI:”, output)

Usando o wget com Python: casos de uso

Esta é a sintaxe de um comando wget:

wget [options] [url]

Onde:

  • [options] é uma lista das opções e sinalizadores suportados pela ferramenta CLI para personalizar seu comportamento.
  • url é o URL do arquivo que você deseja baixar. Pode ser um link direto para um arquivo ou um URL de uma página da web contendo links para vários arquivos.

Nota: no Windows, escreva wget.exe em vez de wget.

É hora de ver o wget em ação em alguns trechos de Python que tratam casos de uso populares!

Baixar um arquivo

Suponha que você queira baixar o http://lumtest.com/myip.json com wget. O comando para conseguir isso seria:

wget http://lumtest.com/myip.json

Em Python, tornaria-se a seguinte linha de código:

output, error = execute_command("wget http://lumtest.com/myip.json")

Se você imprimir a saída, verá algo como:

--2024-04-18 15:20:59-- http://lumtest.com/myip.json

Resolving lumtest.com (lumtest.com)... 3.94.72.89, 3.94.40.55

Connecting to lumtest.com (lumtest.com)|3.94.72.89|:80... connected.

HTTP request sent, awaiting response... 200 OK

Length: 266 [application/json]

Saving to: 'myip.json.1'

myip.json.1 100%[=================================================>] 266 --.-KB/s in 0s

2024-04-18 15:20:59 (5.41 MB/s) - 'myip.json.1' saved [266/266]

A partir da saída do comando, você pode ver que:

  1. O URL está resolvido para o endereço IP do servidor.
  2. wget se conecta ao servidor por meio de uma solicitação HTTP para o recurso especificado.
  3. código de status de resposta HTTP recebido pelo servidor é 200.
  4. wget baixa o arquivo e o armazena no diretório atual.

Seu diretório do projeto Python agora conterá um arquivo myip.json.

Se você quiser alterar a pasta de destino onde armazenar o arquivo a ser baixado, use o –directory-prefix ou -P conforme abaixo:

output, error = execute_command("wget --directory-prefix=./download http://lumtest.com/myip.json")

O arquivo myip.json agora será armazenado na pasta de download dentro do diretório do seu projeto. Note que se a pasta de destino não existir, wget a criará automaticamente.

Para alterar o nome do arquivo do recurso de download, use o sinalizador –output-document ou -O:

output, error = execute_command("wget --output-document=custom-name.json http://lumtest.com/myip.json")

Desta vez, o script Python wget criará um arquivo chamado custom-name.json em vez de myip.json.

Baixar uma página da web

O comando wget é o mesmo de antes, com a principal diferença de que desta vez o URL apontará para uma página da web:

output, error = execute_command("wget https://brightdata.com/")

O diretório do seu projeto agora conterá um arquivo index.html com o conteúdo HTML da página da web em https://brightdata.com/.

Baixe um arquivo somente se ele tiver alterações desde o último download

Para economizar espaço em disco e recursos de rede, talvez você não queira baixar um arquivo se ele não tiver sido alterado desde o último download. Veja por que wget oferece recursos de carimbo de data e hora do arquivo.

Em detalhes, a opção –timestamping instrui wget a comparar os carimbos de data e hora dos arquivos locais com os do servidor. Se o arquivo local tiver a mesma data e hora do que as do servidor, ou for mais recente, wget não baixará o arquivo novamente. Caso contrário, ele o baixará.

É assim que o mecanismo de carimbo de data e hora funciona:

  1. Quando você baixa um arquivo usando a opção –timestamping ou -N, wget recupera o carimbo de data e hora do arquivo remoto.
  2. Ele verifica a data e hora do arquivo local (se existir) e as compara com a data e hora do arquivo remoto.
  3. Se o arquivo local não existir ou se a data e hora forem mais antigas que as do servidor, wget baixará o arquivo. Se o arquivo local existir e sua data e hora forem as mesmas ou mais recentes do que as do servidor, wget não fará o download do arquivo.

O registro de data e hora em HTTP é implementado verificando o cabeçalho Last-Modified retornado pelo servidor após uma solicitação HEAD. wget também examinará o cabeçalho Content-Length para comparar os tamanhos dos arquivos. Se não forem iguais, o arquivo remoto será baixado independentemente do que diz o cabeçalho Last-Modified. Lembre-se de que Last-Modified é um cabeçalho de resposta opcional. Se não estiver presente, wget baixará o arquivo de qualquer maneira.

Use a opção –timestamping em Python com a seguinte linha de código:

output, error = execute_command("wget --timestamping https://brightdata.com")

Se você já baixou index.hml, você receberá a mensagem abaixo indicando que o arquivo não será baixado novamente:

--2024-04-18 15:55:06-- https://brightdata.com

Resolving brightdata.com (brightdata.com)... 104.18.25.60, 104.18.24.60

Connecting to brightdata.com (brightdata.com)|104.18.25.60|:443... connected.

HTTP request sent, awaiting response... 304 Not Modified

File 'index.html' not modified on server. Omitting download.

O mesmo mecanismo também funciona ao baixar arquivos via FTP.

Completar downloads interrompidos

Por padrão, wget tenta automaticamente baixar um arquivo até 20 vezes se a conexão for perdida durante o processo. Se você quiser continuar manualmente um arquivo parcialmente baixado, use a opção –continue ou -c da seguinte forma:

output, error = execute_command("wget --continue http://lumtest.com/myip.json")

Baixar um site inteiro

O download recursivo é um recurso wget para baixar um site inteiro com um único comando.

Começando pelo URL especificado, wget analisa a página HTML e segue os outros documentos encontrados nos atributos HTML src e href ou nos atributos CSS url (). Se o próximo arquivo também for um arquivo de texto/HTML, ele o analisará e acompanhará seus documentos até atingir a profundidade desejada. O download recursivo segue um algoritmo de busca que prioriza a amplitude, recuperando arquivos na profundidade 1, depois na profundidade 2 e assim por diante.

As opções wget que você deve ter em mente ao usar este modo de download são:

  • –recursive ou -r: instrui wget a baixar arquivos recursivamente, o que significa que ele seguirá os links nas páginas da web. Permite que você crie cópias locais de sites inteiros, incluindo todos os recursos vinculados, como imagens, folhas de estilo, scripts etc. Quando essa opção é especificada, wget armazena todos os arquivos baixados em uma pasta com o mesmo nome de domínio do site de destino.
  • –level=<depth> ou -l=<depth>: especifica a profundidade máxima de recursão a ser seguida ao baixar páginas vinculadas. Por exemplo, se você definir –level=1, wget baixará somente as páginas vinculadas diretamente do URL inicial. Ele não seguirá os links dessas páginas para baixar outras páginas. Para evitar o rastreamento de sites grandes, o valor de profundidade padrão é 5. Defina essa opção como 0 ou ‘inf’ para profundidade infinita. Se você quiser garantir que todos os recursos necessários para exibir corretamente uma página sejam baixados, independentemente da profundidade especificada, adicione a opção -p ou –page-requisites.
  • –convert-links ou -k: modifica os links nos arquivos HTML baixados para apontar para os arquivos baixados localmente em vez dos URLs originais. Essa opção é útil quando você deseja criar um espelho local de um site e garantir que todos os links nas páginas baixadas funcionem corretamente offline.

Suponha que você queira baixar recursivamente o site Bright Data com uma profundidade máxima de 1 enquanto converte todos os links para apontar para arquivos locais. Essa é a instrução Python wget que você deve escrever:

output, error = execute_command("wget --recursive --level=1 --convert-links https://brightdata.com")

Nota: esse comando pode demorar um pouco com base na velocidade da sua conexão com a Internet, então seja paciente.

A pasta brightdata.com agora conterá uma cópia local dos arquivos do site Bright Data com 1 nível de profundidade de recursão.

Prós e contras de usar wget com Python

Vamos ver os prós e os contras de usar wget com Python.

 Prós

  • Fácil integração com Python graças ao módulo subprocess.
  • Toneladas de recursos e opções, incluindo download recursivo, novas tentativas automáticas, registro de arquivos e muito mais.
  • Pode fazer uma cópia local de um site inteiro com um único comando.
  • Suporte a FTP.
  • Suporte para integração de proxy.
  • Capacidade de recuperar downloads interrompidos.

 Contras

  • A saída são arquivos baixados e não variáveis de string que você pode usar diretamente no script Python.
  • Você precisa de um analisador como Beautiful Soup para acessar elementos DOM específicos dos arquivos HTML baixados.

[Extra] Usando o wget com um proxy

O principal desafio de usar wget para baixar um arquivo ou um site inteiro é que suas solicitações podem ser bloqueadas. Isso ocorre porque as solicitações wget aparecerão nos servidores de destino como provenientes de um bot. Para se proteger contra elas, alguns sites implementam restrições e limitações para suas páginas e recursos. Essas limitações podem incluir restrições geográficas, políticas de limitação de taxas ou medidas antiscraping.

Integrar um servidor proxy em wget é uma solução viável para contornar essas restrições. Um proxy atua como um servidor intermediário entre o computador e a internet. Ao encaminhar o tráfego de wget por meio de um servidor proxy, você pode evitar expor seu IP e contornar a maioria das limitações impostas pelos sites.

Para um tutorial mais completo, consulte nosso guia sobre como usar um proxy com Wget.

Conclusão

Neste artigo, você entendeu o que é wget, por que ele pode ser melhor do que a biblioteca requests e como usá-lo em Python. Agora você sabe que wget é uma ferramenta poderosa para baixar arquivos e páginas da web por HTTP, HTTPS e FTP. Graças ao que você aprendeu aqui, você sabe como usar wget com Python.

Conforme visto neste guia, um proxy pode ser um ótimo aliado para evitar todas as medidas anti-bot que os sites adotam para impedir que utilitários como wget baixem seu conteúdo. O problema é que existem dezenas de provedores online e escolher o melhor não é fácil. Economize tempo e escolha diretamente o melhor do mercado: a Bright Data.

A Bright Data controla os melhores servidores de proxy do mundo, atendendo a empresas listadas na Fortune 500 e a mais de 20.000 clientes. Sua oferta inclui uma grande variedade de tipos de proxy:

  • Proxies de data centers — mais de 770.000 IPs de data centers.
  • Proxies residenciais — mais de 72 milhões de IPs residenciais em mais de 195 países.
  • Proxies de ISP — mais de 700.000 IPs de ISP.
  • Proxies móveis — mais de 7 milhões de IPs móveis.

Comece com um teste gratuito ou converse com um de nossos especialistas em dados sobre as nossas soluções de proxy e scraping.