Skip to main content

Extratores Python — HTML para SQLite

Scripts que leem os arquivos HTML exportados do sistema acadêmico da UTFPR e gravam as informações em bancos SQLite3. São a primeira etapa do pipeline; os bancos gerados aqui alimentam a parte Node (gerar-json.js → JSON → páginas MDX do Docusaurus).

HTML (UTFPR) ──(extrair_*.py)──► bancos/*.db ──(Node)──► *.json ──► *.mdx
ScriptEntrada (HTML)Saída
extrair_planejamento.pyPlanejamento de Aulasincrona.db, assincrona.db, procedimentos.db
extrair_permanencia.pyMapa de Aulas e Permanênciaspermanencia.db (+ view vw_mapa)
extrair_salas.pyMapa de aula da salasalas.db (+ view vw_salas) e salas.json

Requisitos​

  • Python 3.9+ (os scripts usam argparse.BooleanOptionalAction).
  • beautifulsoup4.
python3 -m pip install beautifulsoup4 # Linux/macOS
py -m pip install beautifulsoup4 # Windows

Convenções comuns de linha de comando​

Os três scripts compartilham a mesma interface:

python3 extrair_XXX.py arquivo.html # um arquivo
python3 extrair_XXX.py *.html # vários
python3 extrair_XXX.py --dir ./htmls # todos os .html da pasta
python3 extrair_XXX.py --dir ./htmls --out ./bancos

Sem argumentos, procuram por *.html no diretório atual.

Destino do banco (--out):

  • informado → usa o diretório indicado;
  • omitido + --dir X → grava em X/bancos (ex.: ./htmls → ./htmls/bancos);
  • omitido e sem --dir → diretório atual.

Limpeza (--limpar / --no-limpar): por padrão (--limpar) a tabela é esvaziada antes de inserir (execução idempotente, sem duplicar). Use --no-limpar para acrescentar — útil ao acumular várias disciplinas/salas no mesmo banco.

Aceitam vários arquivos numa só execução, acumulando no mesmo banco.

extrair_planejamento.py​

Extrai as Atividades Síncrona, Assíncrona e os Procedimentos de Ensino do Planejamento de Aula, gravando cada item em um banco distinto.

python3 extrair_planejamento.py --dir ./htmls
BancoTabelaCampos principais
sincrona.dbatividades_sincronassemana, data, cht, ch_planejada, professor, conteudo_previsto
assincrona.dbatividades_assincronassemana, data_inicio, data_fim, ch_ead, conteudo_previsto
procedimentos.dbprocedimentos_ensinoatividade, descricao

Todos os registros guardam também arquivo, disciplina, codigo (ex.: ELT73A-S22) e professor_disciplina.

extrair_permanencia.py​

Extrai o Mapa de Aulas e Permanências (grade semanal). Cada célula preenchida vira um registro na tabela enxuta mapa_aulas_permanencias:

id, arquivo, professor, periodo, tipo, codigo_slot,
atividade, codigo, turma, sala, turma_extra

A posição na grade fica apenas em codigo_slot (ex.: 2N3 = dia 2 / Noite / slot 3). Os campos derivados (dia da semana, turno, slot, horário) são obtidos pela view vw_mapa:

SELECT codigo_slot, dia_semana, turno, slot, horario, codigo, turma, sala
FROM vw_mapa ORDER BY dia_indice, slot;

tipo é Aula quando há código de disciplina; senão Permanência.

extrair_salas.py​

Extrai o Mapa de aula da sala (grade da sala) e gera dois artefatos: salas.db (tabela mapa_salas + view vw_salas) e salas.json.

python3 extrair_salas.py CA-011.html
python3 extrair_salas.py *.html --json ./src/data/salas.json

Tabela mapa_salas:

id, arquivo, sala, laboratorio, capacidade, periodo, codigo_slot,
atividade, codigo, turma, professor, turma_extra

Cada célula tem 4 linhas — ex.: AMPLIFICADORES | ELT74E-S25 CA-011 | ELISABETE | B43 → atividade AMPLIFICADORES, código ELT74E, turma S25, sala CA-011, professor ELISABETE, turma extra B43. Códigos longos de pós-graduação também são separados corretamente (ex.: PPGSEPAE17-PGSE → PPGSEPAE17 / PGSE).

Opção extra:

OpçãoPadrãoDescrição
--json <arquivo><out>/salas.jsonCaminho do salas.json gerado.

O salas.json sai no mesmo formato produzido pela parte Node, então você pode gerá-lo aqui ou pelo gerar-json.js (lendo salas.db) — os dois são equivalentes.

Sobre codigo_slot e as views​

codigo_slot codifica dia + turno + slot (ex.: 3M1 = Terça, Manhã, slot

  1. — é o mesmo valor do <select> de horários do sistema. As views vw_mapa / vw_salas decodificam isso em dia_indice, dia_semana, turno, slot e horario (grade padrão UTFPR Curitiba: M1 07:30 … N5 22:10), evitando guardar colunas redundantes.

Migração de schema​

extrair_permanencia.py e extrair_salas.py detectam bancos criados por versões anteriores (com schema diferente) e recriam a tabela enxuta + view automaticamente. extrair_planejamento.py mantém o schema estável.

Consultando os bancos​

Sem o CLI sqlite3 instalado, use Python:

import sqlite3
con = sqlite3.connect("bancos/permanencia.db")
con.row_factory = sqlite3.Row
for r in con.execute("SELECT * FROM vw_mapa ORDER BY dia_indice, slot"):
print(dict(r))

Solução de problemas​

  • ModuleNotFoundError: No module named 'bs4' — instale beautifulsoup4.
  • Nenhum arquivo HTML encontrado. — confira o caminho de --dir ou os nomes dos arquivos; sem argumentos, só o diretório atual é varrido.
  • Registros duplicados — provavelmente --no-limpar foi usado sobre os mesmos arquivos; rode no modo padrão (--limpar) para regravar do zero.
  • Bancos no Dropbox travando na leitura — pause a sincronização por um instante ou copie os .db para uma pasta local antes de rodar a parte Node.

Próxima etapa (parte Node)​

Depois de gerar os .db, gere os JSON e as páginas MDX:

node scripts/gerar-json.js --db-dir ./bancos --out ./src/data
node scripts/gerar-mdx.js

Veja a parte Node para detalhes.