Covil Do Dev

Como baixar arquivos de URLs utilizando Python

Aprenda a baixar arquivos de URLs utilizando Python e gerenciar o processo de download de dados. Você aprenderá sobre streaming de dados, pools de threads e downloads assíncronos.

Lindomar Rodrigues

Atualizado

Existem diversas ferrametas e biliotecas em Python que são úteis para se lidar com download de arquivos, que podem ser utilizadas em diversas aplicações, desde web scraping até scripts que automatizam tarefas e fazem análise de dados.

Baixar arquivos de uma URL de forma programática é uma habilidade útil para diversos projetos e fluxos de trabalho.

Neste tutorial, você aprenderá a:

  • Download de arquivos da Web utilizando a biblioteca padrão (urllib) e também bibliotecas de terceiros em Python.

  • Gerenciar o processo de download de dados.

  • Streaming de dados para baixar arquivos grandes em pedaços gerenciáveis.

  • Downloads paralelos utilizando uma pool de threads.

  • Downloads assíncronos para baixar múltiplos arquivos em massa.

Baixando arquivos de uma URL em Python

Quando você precisa baixar um arquivo de uma URL em Python, você pode utilizar a biblioteca padrão urllib ou uma biblioteca de terceiros, como requests.

Enquanto a biblioteca urllib vem com o Python na sua biblioteca padrão, ela tem algumas limitações. Por isso, você também aprenderá a utilizar a biblioteca requests, que é uma biblioteca de terceiros que oferece mais recursos para fazer requisições HTTP.

Utilizando a biblioteca padrão (urllib)

Uma das bibliotecas que vem por padrão no Python é a urllib, que fornece uma forma conveniente de interagir com recursos da internet.

Utilizando urllib você pode realizar diversas tarefas que envolva comunicação em rede, como fazer requisições HTTP, realizar parse de URLs, baixar arquivos e lidar com erros relacionados a operações de rede.

Por ser uma biblioteca padrão, a urllib não tem dependências externas e não requer a instalação de pacotes adicionais, o que a torna uma escolha conveniente. Por esse mesmo motivo, ela é simples de ser utilizada em protótipos rápidos e em projetos pequenos.

Ela também é compatível com diferentes plataformas, o que significa que você pode escrever e executar código utilizando a biblioteca urllib em diferentes sistemas operacionais sem a necessidade de instalar dependências adicionais ou realizar configurações extras.

A biblioteca urllib também é muito versátil. Ela se integra bem com outros módulos padrões do Python, como o re para construir e manipular expressões regulares, e o json para trabalhar com dados no formato JSON.

Utilizar urllib em conjunto com o json é particularmente útil quando você precisa consumir APIs que retornam dados em formato JSON.

Além disso, você pode estender a biblioteca urllib e utilizá-la em conjunto com outras bibliotecas de terceiros, como requests, BeautifulSoup e Scrapy.

Essa possibilidade é útil para casos de uso mais avançaos, como web scraping, crawling ou interagir com APIs mais sofisticadas.

Para baixar um arquivo de uma URL utilizando a biblioteca urllib, você pode chamar a função urlretrieve do módulo urllib.request.

Essa função busca um recurso da internet a partir da URL especificada e salva a resposta em um arquivo local.

Para começar, importe a função urlretrieve do módulo urllib.request:

from urllib.request import urlretrieve 

Após importar, defina a URL de onde você deseja baixar os dados.

Se você não especificar um caminho para um arquivo local onde você deseja salvar os dados, a função urlretrieve irá criar um arquivo temporário para você.

Então você pode baixar o arquivo chamando a função urlretrieve e passando a URL e opcionalmente o nome do arquivo:

from urllib.request import urlretrieve 

url = "https://api.worldbank.org/v2/en/indicator/NY.GDP.MKTP.CD?downloadformat=csv"
filename = "gdp_por_pais.zip"

urlretrieve(url, filename)
# Retorno: ('gdp_por_pais.zip', <http.client.HTTPMessage object at 0x7f06ee7527d0>)

Essa função retorna uma tupla com dois objetos: o caminho para o arquivo de saída e um objeto HTTPMessage.

Quando você não especifica um nome de arquivo personalizado, você verá um caminho para um arquivo temporário que pode parecer com isso: /tmp/tmps7qjl1tj.

O objeto HTTPMessage representa os cabeçalhos HTTP retornados pelo servidor para a requisição, que podem conter informações como o tipo de conteúdo, o tamanho do conteúdo e outros metadados.

Você pode desempacotar a tupla em variáveis individuais utilizando uma atribuição e iterar sobre os headers como se fosse um dicionário do Python.

path, headers = urlretrieve(url, filename)
for nome, valor in headers.items():
    print(nome, valor)

Essas informações podem ser úteis quando você não tem certeza sobre qual formato de arquivo você acabou de baixar e como você deve interpretar o seu conteúdo.

Nesse caso, é um arquivo ZIP que tem cerca de 128 kilobytes de tamanho. Você também pode deduzir o nome do arquivo original, que era API_NY.GDP.MKTP.CD_DS2_en_csv_v2_5551501.zip.

Utilizando a biblioteca requests

Enquanto a urllib é uma boa opção que vem por padrão no Python, pode haver cenários em que você precise utilizar bibliotecas de terceiros para fazer requisições HTTP mais avançadas, como aquelas que requerem algum tipo de autenticação.

A biblioteca requests é uma API popular, amigável e Pythonica para fazer requisições HTTP em Python. Ela pode lidar com as complexidades da comunicação de rede de baixo nível por trás dos panos.

A biblioteca requests também é conhecida por sua flexibilidade e oferece um controle mais preciso sobre o processo de download, permitindo que você o personalize de acordo com os requisitos do seu projeto.

Alguns exemplos incluem a capacidade de especificar cabeçalhos de requisição, lidar com cookies, acessar dados por trás de páginas da web com login, transmitir dados em pedaços e muito mais.

Além disso, a biblioteca é projetada para ser eficiente e performática, suportando vários recursos que melhoram o desempenho geral do download.

Vamos ver como ficaria o exemplo anterior utilizando a biblioteca requests para baixar o mesmo arquivo ZIP com os dados de GDP por país da plataforma World Bank Open Data.

Primeiramente, precisamos instalar a biblioteca requests utilizando o pip:

pip install requests

Esse comando instala a última versão da biblioteca requests no seu ambiente.

Para utilizar a biblioteca, basta importá-la:

import requests

Antes de prosseguir, vale a pena relembrar os métodos HTTP disponíveis, pois a biblioteca requests os expõe para você através de funções comuns do Python.

Existem diversas formas de fazer requisições HTTP para servidores web, mas os dois métodos mais comuns são o GET e o POST, vamos ver oque significa cada um deles.

GET

O método GET é utilizado para recuperar dados solicitando uma representação do recurso remoto sem modificar o estado do servidor.

Por isso, ele é comumente utilizado para recuperar arquivos como imagens, páginas web em HTML ou dados brutos.

Será esse o método que iremos utilizar nos exemplos, e provavelmente será o que vocêe mais utilizará em projetos reais também.

Quando você acessa uma página WEB pelo navegador, o método utilizado é o GET.

POST

O método POST permite que você envie dados para o servidor para serem processados ou utilizados na criação ou atualização de um recurso.

Em requisições POST, os dados são tipicamente enviados no corpo da requisição em diversos formatos como JSON ou XML, e não são visíveis na URL.

Você pode utilizar requisições POST para operações que modificam dados no servidor, como criar, atualizar ou enviar recursos existentes ou novos.

Neste tutorial, você utilizará apenas requisições GET para baixar arquivos.

Agora defina a URL do arquivo que você deseja baixar e inclua os parâmetros de consulta(query parameters) na URL passando um dicionário de strings como pares chave-valor:

url = "https://api.worldbank.org/v2/en/indicator/NY.GDP.MKTP.CD"
query_parameters = {"downloadformat": "csv"}

No exemplo acima, você define a mesma URL de antes, mas especifica o parâmetro downloadformat=csv separadamente utilizando um dicionário do Python.

A biblioteca irá anexar esses parâmetros na URL após você passá-los para a função requests.get utilizando um argumento opcional chamado params.

response = requests.get(url, params=query_parameters)

Isso faz uma requisição GET para recuperar dados da URL construída com os parâmetros de consulta opcionais (query parameters).

A função retorna um objeto HTTP response com a resposta do servidor para a requisição.

Se você quiser ver a URL construída com os parâmetros opcionais incluídos, utilize o atributo .url do objeto.

response.url
# Retorno: 'https://api.worldbank.org/v2/en/indicator/NY.GDP.MKTP.CD?downloadformat=csv'

O objeto response fornece vários outros atributos convenientes que você pode verificar.

Por exemplo, esses dois irão permitir que você determine se a requisição foi bem sucedida e qual o código de status HTTP que o servidor retornou:

response.ok
# Retorno: True

response.status_code
# Retorno: 200

Um código de status(status code) 200 indica que a sua requisição foi concluída com sucesso.

Tudo bem, mas como você acessa o payload de dados, geralmente no formato JSON, que você recuperou com a biblioteca requests?

Continue lendo para responder a essa pergunta na próxima seção.

Salvando o conteúdo baixado em um arquivo

Após recuperar o conteúdo de uma URL utilizando a biblioteca requests, você pode salvá-lo em um arquivo no seu computador.

Ao salvar dados em um arquivo em Python, é altamente recomendável utilizar o with, pois ele garante que o Python gerencie corretamente os recursos, incluindo arquivos, e os feche automaticamente quando você não precisar mais deles.

Existem algumas maneiras de acessar os dados recuperados com a biblioteca requests, dependendo do tipo de conteúdo.

Em particular, quando você deseja salvar os dados originais em um arquivo local, você utilizará o atributo .content do objeto response retornado.

Como esse atributo contém bytes brutos, você irá abrir um novo arquivo em modo binário para escrita ('wb') e então escrever o conteúdo baixado nesse arquivo:

with open("gdp_por_pais.zip", mode="wb") as file:
    file.write(response.content)

O que você vê na saída é o número de bytes salvos no arquivo. Nesse caso, ele é consistente com o tamanho do conteúdo que você viu anteriormente.

Baixando um arquivo grande em streaming

Você já viu como baixar um único arquivo ZIP utilizando tanto a biblioteca padrão urllib quanto a biblioteca requests.

Se o seu projeto requer baixar um arquivo maior, você pode ter problemas utilizando os passos acima quando você tentar carregar o arquivo inteiro na memória.

Para superar esses problemas, você pode baixar arquivos grandes em um streaming para evitar ler o conteúdo de respostas grandes de uma só vez.

Streaming de dados também oferece vantagens em outros cenários ao baixar arquivos em Python, como a capacidade de:

  • **Baixar e processar um arquivo em pedaços menores: ** Isso é útil quando uma rede impõe restrições no tamanho da transferência de dados em uma única requisição. Nesses casos, o streaming de dados pode permitir que você ignore essas limitações para baixar e processar o arquivo em pedaços menores.

  • **Processar e consumir os dados em tempo real: ** Ao processar os dados conforme eles chegam, você pode utilizar e extrair insights do conteúdo baixado do arquivo enquanto os dados restantes continuam a ser baixados.

  • **Pausar e retomar o processo de download: ** Isso permite que você baixe uma parte do arquivo, pause a operação e depois retome de onde parou, sem ter que reiniciar o download inteiro.

Para baixar um arquivo grande em um streaming, você manteria a conexão da requisição aberta e baixaria apenas os cabeçalhos de resposta definindo o argumento stream na função requests.get.

Abaixo temos um exemplos onde baixamos um arquivo ZIP grande, que tem cerca de 72 megabytes, contendo os Indicadores de desenvolvimento globais da plataforma World Bank Open Data:

url = "https://databank.worldbank.org/data/download/WDI_CSV.zip"
response = requests.get(url, stream=True)

O parâmetro stream=True faz com que a biblioteca requests envie uma requisição GET para a URL especificada em um streaming, que baixa apenas os cabeçalhos de resposta HTTP primeiro.

Você pode ver esses cabeçalhos de resposta acessando o atributo .headers do objeto recebido:

response.headers

Como você pode ver, um dos cabeçalhos informa que o servidor mantém a conexão ativa para você.

Essa é uma conexão HTTP persistente, que permite que você envie potencialmente várias requisições HTTP dentro de uma única conexão de rede.

Caso contrário, você teria que estabelecer uma nova conexão TCP/IP para cada requisição de saída, o que é uma operação cara que leva tempo.

Outra vantagem do modo streaming na biblioteca requests é que você pode baixar dados em pedaços, mesmo quando envia apenas uma requisição.

Para fazer isso, utilize o método .iter_content() fornecido pelo objeto response, que permite que você itere pelos dados de resposta em pedaços gerenciáveis.

Além disso, você pode especificar o tamanho do pedaço utilizando o parâmetro chunk_size, que representa o número de bytes que ele deve ler na memória.

Com o streaming de dados, você vai querer salvar o conteúdo baixado localmente conforme avança no processo de download:

with open("WDI_CSV.zip", mode="wb") as file:
    for chunk in response.iter_content(chunk_size=10 * 1024):
        file.write(chunk)

Você especifica um nome de arquivo ou caminho desejado e abre o arquivo em modo binário (wb) utilizando o with para um melhor gerenciamento de recursos.

Em seguida, você itera pelos dados de resposta utilizando response.iter_content(), escolhendo um tamanho de pedaço opcional, que é 10 kilobytes neste caso.

Por fim, você escreve cada pedaço no arquivo dentro do corpo do loop.

Download de vários arquivos em paralelo

Você está ficando melhor em baixar um único arquivo em diferentes cenários utilizando o Python, no entanto, na vida real, você frequentemente vai querer baixar mais de um arquivo ao mesmo tempo.

Por exemplo, você pode precisar buscar um conjunto de documentos de fatura em um determinado período de tempo ou baixar um conjunto de imagens de um site.

Nessa seção, você vai explorar algumas maneiras diferentes de baixar vários arquivos de uma só vez em Python.

Baixar vários arquivos é mais um cenário comum em Python. Nesse caso, você pode acelerar o processo de download obtendo os arquivos em paralelo.

Existem duas abordagens populares para baixar vários arquivos simultaneamente:

  1. Utilizando um pool de threads com a biblioteca requests.
  2. Utilizando downloads assíncronos com a biblioteca aiohttp.

Abordaremos ambos os métodos nesse artigo, começando com o primeiro.

Utilizando um pool de threads com a biblioteca requests

Quando você deseja fazer muitas requisições HTTP para os mesmos ou diferentes servidores, você pode aproveitar o multithreading para diminuir o tempo de execução geral do seu código.

Em um programa multithreaded, você normalmente cria vários threads de execução, cada um com sua própria sequência de instruções que é executada independentemente e em paralelo com os outros.

Esses threads podem executar tarefas diferentes ou executar outras partes do programa simultaneamente, melhorando o desempenho e maximizando o uso dos núcleos da CPU, por exemplo, cada thread pode fazer sua própria requisição HTTP.

Baixaremos 3 arquivos ZIP da World Bank Open Data platform, sendo eles:

  1. População total por país
  2. PIB por país
  3. Densidade populacional por país

Nesse exemplo, você utilizará um pool de threads com a biblioteca requests para entender como realizar o download de arquivos em paralelo.

Primeiro, importe a classe ThreadPoolExecutor do módulo concurrent.futures e a biblioteca requests novamente:

from concurrent.futures import ThreadPoolExecutor
import requests

Após isso, escreva uma função que você executará em cada thread para baixar um único arquivo de uma determinada URL:

def download_file(url):
     response = requests.get(url)
     if "content-disposition" in response.headers:
         content_disposition = response.headers["content-disposition"]
         filename = content_disposition.split("filename=")[1]
     else:
         filename = url.split("/")[-1]
     with open(filename, mode="wb") as file:
         file.write(response.content)
     print(f"Downloaded file {filename}")

Essa função recebe uma URL como argumento, faz uma requisição GET utilizando a biblioteca requests e salva os dados recuperados em um arquivo local.

Nesse exemplo específico, ela primeiro tenta extrair o nome do arquivo do cabeçalho de resposta Content-Disposition, que contém informações sobre quais itens na página são exibidos inline versus como anexos.

Se isso não estiver disponível, então ele obtém o nome do arquivo de uma parte da URL.

Você baixará três arquivos separados da mesma API, então crie um modelo de URL e preencha uma lista Python com ele:

template_url = (
    "https://api.worldbank.org/v2/en/indicator/"
    "{resource}?downloadformat=csv"
)

urls = [
    # População total por país
    template_url.format(resource="SP.POP.TOTL"),

    # GDP por país
    template_url.format(resource="NY.GDP.MKTP.CD"),

    # Densidade populacional por país
    template_url.format(resource="EN.POP.DNST"),
]

Aqui, você chama o método .format() na string de template com diferentes nomes de recursos que correspondem a arquivos ZIP com dados CSV em um servidor remoto.

Para baixar esses arquivos em paralelo utilizando vários threads de execução, crie um novo pool de threads e mapeie sua função download_file() em cada item da lista:

with ThreadPoolExecutor() as executor:
     executor.map(download_file, urls)

Como antes, você utiliza o with para ajudar no gerenciamento de recursos para seus threads.

Dentro do contexto do executor, você chama o método .map() com a função que você deseja executar.

Você também passa um iterável, que é a lista de URLs neste caso e o objeto executor aloca um pool de threads antecipadamente e atribui um thread separado para cada tarefa de download.

Como baixar dados de uma rede é uma tarefa I/O-bound, que é limitada pela velocidade com que os dados podem ser lidos em vez da velocidade da CPU, você alcança o verdadeiro paralelismo.

Apesar do bloqueio global do interpretador, que de outra forma impediria isso, os threads no executor executam várias tarefas em paralelo, resultando em um tempo de conclusão geral mais rápido.

Os arquivos ZIP de exemplo são relativamente pequenos e semelhantes em tamanho, então eles terminam de baixar aproximadamente ao mesmo tempo.

Mas e se você usasse um for loop para baixar os arquivos em vez disso?

for url in urls:
    download_file(url)

Você pode ter percebido que essa operação demorou muito mais, isso porque os arquivos foram baixados sequencialmente em vez de paralelamente.

Portanto, quando o primeiro arquivo começa a ser baixado, o segundo não começa até que ele termine e assim por diante.

Isso significa que o tempo total necessário para baixar todos os arquivos é a soma dos tempos de download de cada arquivo individual.

Infelizmente, usar threads nem sempre é desejável devido à sua complexidade.

O exemplo desta seção foi bastante simples porque você não precisou se preocupar com sincronização de threads, coordenação ou gerenciamento de recursos.

Mas ao trabalhar com código multithreaded, você deve ter cuidado com a segurança de threads

Existem algumas condições em que o multithreading pode não melhorar seu desempenho.

Se o problema subjacente for inerentemente sequencial, não há como paralelizá-lo.

Além disso, se suas tarefas envolverem operações CPU-bound, o Python não poderá aproveitar vários núcleos da CPU por causa do GIL.

O custo adicional da troca de contexto pode realmente reduzir o desempenho!

Utilizando a biblioteca assíncrona aiohttp

Além do multithreading, outro método para baixar vários arquivos simultaneamente é utilizando o padrão async/await em Python.

Isso envolve a execução de várias tarefas não bloqueantes assincronamente em um loop de eventos permitindo que elas suspendam e retomem a execução voluntariamente como uma forma de multitarefa cooperativa.

Isso é diferente de threads, que requerem um agendador preemptivo para gerenciar a troca de contexto entre eles.

Tarefas assíncronas também diferem do multithreading pois elas executam simultaneamente dentro de um único thread em vez de vários threads.

Portanto, elas devem periodicamente desistir de seu tempo de execução para outras tarefas sem ocupar a CPU.

Ao fazer isso, tarefas I/O-bound como downloads assíncronos permitem a concorrência, pois o programa pode alternar entre tarefas e progredir em cada uma em paralelo.

Um pacote Python popular para realizar downloads assíncronos ao recuperar vários arquivos é a biblioteca aiohttp.

Ela é construída em cima do módulo asyncio, que fornece um framework para programação assíncrona em Python.

A biblioteca aiohttp aproveita os recursos de concorrência no pacote asyncio, permitindo que você escreva código assíncrono que pode lidar com várias requisições simultaneamente.

A biblioteca pode realizar operações de rede não bloqueantes, o que significa que ela permitirá que outro código seja executado enquanto outra tarefa aguarda a chegada de dados da rede.

Ao utilizar a API aiohttp juntamente com as palavras-chave async def e await, você pode escrever código assíncrono que faz requisições HTTP concorrentes.

Além disso, a biblioteca aiohttp suporta pooling de conexão, um recurso que permite que várias requisições utilizem a mesma conexão subjacente, isso ajuda a otimizar e melhorar o desempenho.

Primeiramente, instale a biblioteca aiohttp utilizando o pip no terminal:

pip install aiohttp

Isso instala a biblioteca aiohttp no seu ambiente.

Além dessa biblioteca de terceiros, você também precisará do pacote asyncio da biblioteca padrão do Python para realizar downloads assíncronos, então importe ambas as bibliotecas agora:

import asyncio
import aiohttp

A próxima etapa é definir uma função assíncrona para baixar um arquivo de uma URL.

Você pode fazer isso criando uma instância aiohttp.ClientSession, que mantém um conector reutilizado para várias conexões.

Ele mantém automaticamente as conexões ativas por um determinado período de tempo para reutilizá-las em solicitações subsequentes ao mesmo servidor sempre que possível.

Isso melhora o desempenho e reduz o custo de estabelecer novas conexões para cada solicitação.

A seguinte função realiza um download assíncrono utilizando a classe ClientSession da biblioteca aiohttp:

 async def download_file(url):
     async with aiohttp.ClientSession() as session:
         async with session.get(url) as response:
             if "content-disposition" in response.headers:
                 header = response.headers["content-disposition"]
                 filename = header.split("filename=")[1]
             else:
                 filename = url.split("/")[-1]
             with open(filename, mode="wb") as file:
                 while True:
                     chunk = await response.content.read()
                     if not chunk:
                         break
                     file.write(chunk)
                 print(f"Downloaded file {filename}")

A função definida acima recebe uma URL como argumento, em seguida, cria uma sessão de cliente utilizando o async with, garantindo que a sessão seja fechada corretamente e os recursos sejam liberados após o programa sair desse bloco de código.

Com o contexto da sessão, ele faz uma solicitação HTTP GET para a URL especificada e obtém o objeto de resposta utilizando o async with.

Dentro do loop infinito, você lê os dados em pedaços, saindo do loop quando não há mais pedaços.

A palavra-chave await indica que essa operação é assíncrona e outras tarefas podem ser executadas em paralelo até que os dados estejam disponíveis.

Após derivar o nome do arquivo do objeto de resposta, você salva o pedaço de dados baixado em um arquivo local.

Depois disso, você pode realizar downloads simultâneos utilizando as capacidades assíncronas das bibliotecas aiohttp e asyncio.

template_url = (
    "https://api.worldbank.org/v2/en/indicator/"
    "{resource}?downloadformat=csv"
)

urls = [
     # População total por país
     template_url.format(resource="SP.POP.TOTL"),

     # GDP por país
     template_url.format(resource="NY.GDP.MKTP.CD"),

     # Densidade populacional por país
     template_url.format(resource="EN.POP.DNST"),
 ]

Por fim, defina e execute uma função assíncrona main() que irá baixar arquivos simultaneamente dessas URLs:

async def main():
     tasks = [download_file(url) for url in urls]
     await asyncio.gather(*tasks)
     
asyncio.run(main())

No trecho acima, a função main() define uma list comprehension para criar uma lista de tarefas, em que cada tarefa chama a função download_file() para cada URL na variável global urls.

Observe que você define a função com a palavra-chave async para torná-la assíncrona.

Em seguida, você usa asyncio.gather() para aguardar até que todas as tarefas da lista sejam concluídas.

Você executa a função main() utilizando asyncio.run(), que inicia e executa as tarefas assíncronas em um loop de eventos.

Este código baixa arquivos simultaneamente das URLs especificadas sem bloquear a execução de outras tarefas.

Qual opção escolher?

Neste ponto, você aprendeu como usar várias ferramentas para baixar arquivos em Python.

Dependendo da tarefa em questão, você pode querer escolher uma opção em vez de outra.

Alguns fatores a serem considerados são o tamanho e o número de arquivos com os quais você estará trabalhando, bem como a facilidade de uso, flexibilidade e recursos adicionais da ferramenta.

Tamanho dos arquivos para download

Se você está procurando baixar arquivos grandes, então a biblioteca requests é uma boa opção que irá lidar com eles eficientemente.

Ela pode fazer stream de dados, permitindo que você itere sobre o corpo da mensagem em pedaços para um processo mais eficiente e melhor uso da memória.

Download de vários arquivos

Ao baixar vários arquivos, você pode usar a biblioteca requests junto com o multithreading ou a biblioteca aiohttp com downloads assíncronos para realizar downloads simultâneos.

Quando usados corretamente, ambos podem melhorar o desempenho e otimizar o processo de download.

Facilidade de uso

Se você está procurando algo rápido e simples, então o pacote urllib já está incluído na biblioteca padrão do Python, não requerendo nenhuma instalação adicional.

Esta é uma boa opção se você quiser baixar arquivos pequenos que possam caber inteiramente na memória sem problemas.

Embora você possa construir muitas funcionalidades usando urllib, pode ser mais difícil de usar e exigir mais configuração manual para casos de uso mais complexos, como streaming de dados e download de vários arquivos em paralelo.

Recursos adicionais e flexibilidade

A biblioteca requests possui um rico conjunto de recursos que podem ajudá-lo em vários outros cenários de download.

Embora não tenhamos coberto extensivamente essas tarefas, a biblioteca requests possui recursos que podem lidar com autenticação, redirecionamentos, gerenciamento de sessão e muito mais.

Esses recursos podem lhe dar mais controle e flexibilidade para tarefas mais avançadas.

Conclusão

Você pode usar o Python para automatizar seus downloads de arquivos ou ter um melhor controle e flexibilidade sobre esse processo. Python oferece várias opções para baixar arquivos de URLs que atendem a diferentes cenários, como arquivos grades, múltiplos arquivos ou arquivos que requerem autenticação para serem baixados.

Neste tutorial, você aprendeu as etapas para baixar arquivos em Python, incluindo:

  • Baixar arquivos da Internet usando bibliotecas internas e externas em Python

  • Realizar stream de dados e baixar arquivos grandes em pedaços menores e mais gerenciáveis

  • Utilizar um pool de threads para buscar vários arquivos concorrentemente

  • Baixar vários arquivos assincronamente ao realizar downloads em massa

Além disso, você viu como usar a biblioteca requests para suas capacidades de streaming e download paralelo.

Se você tiver dúvidas, sinta-se à vontade para entrar em contato na seção de comentários abaixo.

Obrigado por visitar o blog e por ler esse artigo, se tive qualquer dúvida, ideia ou sugestão, não hesite em entrar em contato pelo meu e-mail: lindomar@covildodev.com.br