O acesso a materiais didáticos digitais em plataformas educacionais governamentais muitas vezes é restrito à visualização online. O tchMaterial-parser é uma ferramenta de código aberto desenvolvida em Python que contorna essa limitação, parseando a estrutura de URLs e consumindo APIs internas para obter e baixar arquivos PDF de livros didáticos de forma automatizada.
Configuração do Ambiente e Instalação
Para executar o parser, é necessário um ambiente Python 3.x. Recomenda-se o uso de um ambiente virtual para isolar as dependências do projeto e evitar conflitos de pacotes.
python -m venv venv_parser
source venv_parser/bin/activate # No Windows: venv_parser\Scripts\activate
git clone https://github.com/exemplo/tchMaterial-parser.git extrator_livros
cd extrator_livros
pip install -r requirements.txt
A interface gráfica da aplicação é construída utilizando a biblioteca nativa tkinter. Para iniciar o aplicativo localmente, execute o script principal:
python main_gui.pyw
Arquitetura do Motor de Parseamento
O núcleo da ferramenta analisa a URL da plataforma para extrair metadados essenciais. Abaixo está uma representação refatorada da lógica de extração de parâmetros e requisição à API:
import re
import requests
from urllib.parse import urlparse, parse_qs
class BookExtractor:
BASE_API_URL = "https://api.smartedu.cn/material/detail"
def __init__(self, target_url: str):
self.target_url = target_url
self.content_id = self._extract_id()
def _extract_id(self) -> str:
parsed = urlparse(self.target_url)
query_params = parse_qs(parsed.query)
return query_params.get('contentId', [None])[0]
def fetch_pdf_metadata(self) -> dict:
if not self.content_id:
raise ValueError("ID do conteúdo não encontrado na URL fornecida.")
payload = {"id": self.content_id, "type": "assets_document"}
response = requests.get(self.BASE_API_URL, params=payload, timeout=10)
response.raise_for_status()
data = response.json()
return {
"title": data.get("title", "documento_sem_nome"),
"pdf_url": data.get("fileUrl")
}
Otimização com Multithreading
Para processamento em lote, a ferramenta implementa um pool de threads. Isso permite o download simultâneo de múltiplos livros, gerenciando filas e evitando bloqueios de rede causados por operações I/O síncronas.
from concurrent.futures import ThreadPoolExecutor, as_completed
def download_batch(url_list: list, max_workers: int = 5):
with ThreadPoolExecutor(max_workers=max_workers) as executor:
future_to_url = {executor.submit(process_single_download, url): url for url in url_list}
for future in as_completed(future_to_url):
url = future_to_url[future]
try:
future.result()
except Exception as exc:
print(f"Falha no download de {url}: {exc}")
Tratamento de Erros e Configurações Avançadas
A robustez do script é garantida por mecanismos de retentativa e validação. É possível personalizar a estratégia de salvamento modificando o diretório de saída e aplicando sanitização nos nomes dos arquivos, além de implementar backoff exponencial para lidar com instabilidades de rede.
import os
import time
def safe_download(file_url: str, save_dir: str, retries: int = 3):
os.makedirs(save_dir, exist_ok=True)
filename = sanitize_filename(os.path.basename(file_url))
filepath = os.path.join(save_dir, filename)
for attempt in range(retries):
try:
with requests.get(file_url, stream=True, timeout=15) as r:
r.raise_for_status()
with open(filepath, 'wb') as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
return True
except requests.RequestException:
if attempt == retries - 1:
return False
time.sleep(2 ** attempt) # Backoff exponencial
Recursos Técnicos Principais
- Parseamento de URL: Extração automática de parâmetros
contentIdecontentTypepara montagem de requisições válidas. - Filtragem de Metadados: Suporte a queries estruturadas por nível escolar, disciplina e edição do material através de menus suspensos na GUI.
- Gerenciamento de Sessão: Manutenção de cabeçalhos HTTP para simular requisições de navegador e evitar bloqueios por user-agent.
- Resiliência de Rede: Implementação de retentativas automáticas e verificação de integridade de aqruivos após o download.