Executando verificação de segurança...
5

Single Copier: Uma Ferramenta em Python para Baixar Páginas Web com Todos os Recursos

Introdução

Talvez você já tenha precisado salvar uma página web para visualização offline, completa com todas as suas imagens, estilos, scripts e fontes? Embora os navegadores ofereçam o recurso "Salvar página como", muitas vezes ele não captura todos os recursos com precisão, levando a layouts quebrados ou conteúdo ausente quando visualizado offline. Pensando nisso trabalhei no Single Copier—um script Python projetado para baixar uma página web e todos os seus recursos associados, garantindo que a página pareça e funcione como pretendido quando visualizada localmente.

Neste artigo, mostrarei o que é o Single Copier, como ele funciona e como você pode usá-lo para criar cópias offline de páginas web para análise, arquivamento ou fins educacionais.

Índice

Características

  • Download de Página Única: Baixa a página HTML especificada e todos os recursos referenciados nela.
  • Manipulação de Recursos: Busca imagens, arquivos CSS, arquivos JavaScript, fontes e vídeos.
  • Ajuste de Caminhos: Atualiza automaticamente os caminhos nos arquivos HTML e CSS para apontar para os recursos locais.
  • Download Multithread: Utiliza threads para baixar múltiplos recursos simultaneamente, aumentando a eficiência.
  • Respeito ao Domínio: Limita o download de recursos ao mesmo domínio da URL fornecida.
  • Tratamento de Erros: Fornece logs detalhados para facilitar a solução de problemas.
  • Interface de Linha de Comando: Fácil de usar com argumentos de linha de comando para URL e diretório de saída.

Como o Single Copier Funciona

O Single Copier opera em várias etapas principais:

  1. Inicialização: Configura a estrutura de diretórios para salvar os recursos (imagens, CSS, JS, etc.) e configura a sessão HTTP com cabeçalhos apropriados para imitar um navegador real.

  2. Análise do HTML: Baixa a página web especificada e analisa seu conteúdo HTML usando o BeautifulSoup para identificar todos os recursos vinculados.

  3. Download de Recursos: Encontra todos os URLs de recursos nos arquivos HTML e CSS, e então os baixa usando um pool de threads para concorrência.

  4. Atualização de Caminhos: Modifica os arquivos HTML e CSS para atualizar os URLs dos recursos para seus caminhos locais, garantindo que a página offline faça referência aos recursos baixados.

  5. Tratamento de Erros e Exceções: Captura e registra quaisquer erros encontrados durante o processo de download, como acesso negado a recursos ou problemas de conexão.

Instalação

Pré-requisitos

  • Python 3.6 ou superior
  • pip (gerenciador de pacotes Python)

Pacotes Python Necessários

  • requests
  • beautifulsoup4
  • lxml (opcional, mas recomendado para melhor desempenho na análise de HTML)

Passos

  1. Clone o Repositório ou Baixe o Script

    Você pode clonar o repositório (se hospedado no GitHub) ou simplesmente baixar o script copier.py para sua máquina local.

  2. Instale os Pacotes Necessários

    Abra o terminal ou prompt de comando e execute:

    pip install requests beautifulsoup4 lxml
    

Uso

Para usar o Single Copier, execute o script a partir da linha de comando com a URL da página que você deseja copiar e o diretório de saída desejado.

python copier.py <URL_DA_PÁGINA> <DIRETÓRIO_DE_SAÍDA>

Exemplo:

python copier.py https://exemplo.com/pagina.html pagina_salva

Este comando irá:

  • Baixar https://exemplo.com/pagina.html.
  • Criar um diretório chamado pagina_salva.
  • Salvar todos os recursos em subdiretórios correspondentes dentro de pagina_salva.
  • Gerar um arquivo index.html com caminhos atualizados para os recursos locais.

Entendendo o Código

Vamos nos aprofundar em algumas partes chave do script Single Copier para entender como ele realiza suas tarefas.

Importações e Configuração

import os
import re
import requests
from urllib.parse import urljoin, urlparse, urldefrag
from bs4 import BeautifulSoup
from pathlib import Path
import argparse
import logging
from concurrent.futures import ThreadPoolExecutor
  • requests: Para fazer requisições HTTP.
  • BeautifulSoup: Para analisar o conteúdo HTML.
  • ThreadPoolExecutor: Para download multithread.
  • logging: Para registrar informações e erros.

Configuração da Sessão

session = requests.Session()
session.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
                  'AppleWebKit/537.36 (KHTML, como Gecko) '
                  'Chrome/58.0.3029.110 Safari/537.3'
})
  • Configura uma sessão com um User-Agent personalizado para imitar um navegador real, o que pode ajudar a contornar medidas anti-scraping simples.

Download de Recursos

def download_assets(soup, base_url, base_path, session):
    # Define as tags e seus atributos que podem conter URLs de recursos
    tags = {
        "img": ["src", "srcset"],
        "link": ["href"],
        "script": ["src"],
        "video": ["src"],
        "source": ["src", "srcset"]
    }

    # Processa cada elemento e baixa os recursos
    # ...
  • Execução Multithread: Usa ThreadPoolExecutor para baixar recursos simultaneamente.
  • Limitação por Domínio: Garante que apenas recursos do domínio original sejam baixados.

Atualização de Caminhos

def save_file(url, folder_path, base_path, session):
    # Baixa o arquivo e o salva localmente
    # Retorna o caminho relativo para atualizar no HTML ou CSS
  • Atualiza os caminhos dos recursos nos arquivos HTML e CSS para apontar para as cópias locais.

Manipulação de Arquivos CSS

def process_css_files(css_folder, base_url, base_path, session):
    # Analisa os arquivos CSS para encontrar e baixar recursos como fontes e imagens de fundo
  • Usa expressões regulares para encontrar padrões url() em arquivos CSS.
  • Baixa os recursos referenciados e atualiza os arquivos CSS de acordo.

Tratamento de Erros

except requests.exceptions.HTTPError as e:
    if response.status_code == 401:
        logger.warning(f"Acesso não autorizado ao baixar {url}: {e}")
    else:
        logger.error(f"Erro HTTP ao baixar {url}: {e}")
  • Captura erros HTTP e os registra apropriadamente.
  • Ignora recursos que não podem ser baixados devido a problemas de autorização.

Limitações e Considerações

Limitações

  • Conteúdo Dinâmico: Não lida com conteúdo carregado dinamicamente via JavaScript após o carregamento inicial da página.
  • Recursos Externos: Não baixa recursos de domínios externos (por exemplo, bibliotecas hospedadas em CDNs).
  • Autenticação: Não pode baixar recursos que exigem autenticação além de cabeçalhos básicos.

Considerações Éticas

  • Respeite as Políticas do Site: Sempre verifique os termos de serviço e o arquivo robots.txt do site para garantir que você tem permissão para baixar o conteúdo.
  • Leis de Direitos Autorais: Esteja ciente das restrições de direitos autorais ao copiar conteúdo web.
  • Carga nos Servidores: Use a ferramenta de forma responsável para evitar sobrecarregar servidores web.

Conclusão

O Single Copier fornece uma solução direta para baixar uma única página web junto com todos os seus recursos, garantindo que você possa visualizar a página offline como foi planejada. Seja você um desenvolvedor precisando analisar a estrutura de uma página, um designer procurando estudar técnicas de layout, ou simplesmente alguém que deseja uma cópia offline de uma página, o Single Copier pode ser uma ferramenta valiosa em seu arsenal.

Ao entender como o script funciona e suas limitações, você pode aproveitar ao máximo o Single Copier enquanto o usa de forma responsável e ética.

Recursos Adicionais

Carregando publicação patrocinada...
1
1

Super útil! Com Python então uniu o útil ao agradável! É impressionante o que tem de ferramenta valiosa open source como essa. Obrigadaço por compartilhar!

1

Eu conhecia o processo com wget : ). Valeu por compartilhar essa ideia com os poderes do Pyhton.

Pensando no lado do desenvolvedor do site, uma maneira para lidar com os crawlers é criar a página toda via Javascript, obtendo o conteúdo por websockets seguros (WSS). Tais elementos os crawlers mais simples não conseguem interpretar para obter a página completa.

1