# 🎯 Sistema de Captura Dinâmica de Colunas ## VisĂŁo Geral O scraper agora captura **automaticamente todas as colunas** encontradas nas tabelas do TibiaWiki, sem necessidade de especificar quais colunas buscar. ## 🔄 Como Funciona ### 1. Normalização Automática de Nomes Cada nome de coluna Ă© normalizado para identificador SQL válido: | Coluna no Site | Campo no Banco | |----------------|----------------| | Nome | nome | | Lvl | lvl | | Voc | voc | | MĂŁos | maos | | Atq | atq | | Dano Elemental | dano_elemental | | Def | def | | Mod. de Defesa | mod_de_defesa | | BĂ´nus | bonus | | Slots | slots | | Tier | tier | | Peso | peso | | Dropa de | dropa_de | **Regras de normalização:** - Remove acentos: `NĂvel` → `nivel` - Converte para lowercase: `Atq` → `atq` - Espaços viram underscores: `Dano Elemental` → `dano_elemental` - Remove caracteres especiais: `Mod. de Defesa` → `mod_de_defesa` - Garante nome válido SQL: nĂŁo começa com nĂşmero ### 2. Detecção Automática de Tipo O sistema tenta converter o valor para o tipo mais apropriado: ``` Valor no site → Tipo detectado → Salvo como "150" → INTEGER → 150 "10.5" → REAL → 10.5 "80 oz" → INTEGER → 80 "espada" → TEXT → "espada" "Fire damage" → TEXT → "Fire damage" ``` **Ordem de tentativa:** 1. Tenta converter para INTEGER 2. Se falhar, tenta REAL (float) 3. Se falhar, mantĂ©m como TEXT ### 3. Campos Especiais Alguns campos tĂŞm tratamento especial: | Campo | Tratamento | |-------|-----------| | **(sem nome)** | Imagem do item (`image_url`) | | **agrupável** | Tick/Cross → 1/0 | | **nome** | Sempre TEXT (chave primária) | | **categoria** | Adicionado automaticamente | | **image_url** | ExtraĂdo de colunas sem nome | | **image_local_path** | Preenchido apĂłs download | ### 4. Criação Dinâmica de Colunas Se a tabela já existe mas nĂŁo tem uma coluna: - âś… A coluna Ă© adicionada automaticamente com `ALTER TABLE` - âś… O tipo SQL Ă© detectado baseado no valor - âś… Log informa: "Coluna 'X' adicionada Ă tabela 'Y'" --- ## 📊 Exemplo Prático ### Tabela no Site: Espadas ``` +----------+-------+-----+-----+------+-----+----------------+-----+ | Nome | (img) | Lvl | Voc | MĂŁos | Atq | Dano Elemental | Def | +----------+-------+-----+-----+------+-----+----------------+-----+ | Broadsword | [🖼️] | 0 | - | 1 | 30 | - | 5 | +----------+-------+-----+-----+------+-----+----------------+-----+ ``` ### Banco de Dados Resultante ```sql CREATE TABLE espadas ( id INTEGER PRIMARY KEY AUTOINCREMENT, categoria TEXT, nome TEXT UNIQUE NOT NULL, image_url TEXT, image_local_path TEXT, lvl INTEGER, -- detectado automaticamente voc TEXT, -- detectado automaticamente maos INTEGER, -- detectado automaticamente atq INTEGER, -- detectado automaticamente dano_elemental TEXT, -- detectado automaticamente def INTEGER -- detectado automaticamente ); ``` ### Registro Inserido ```sql INSERT INTO espadas VALUES ( 1, -- id (auto) 'Espadas', -- categoria 'Broadsword', -- nome 'https://...gif', -- image_url 'data/images/...', -- image_local_path 0, -- lvl '-', -- voc 1, -- maos 30, -- atq '-', -- dano_elemental 5 -- def ); ``` --- ## âś… Vantagens ### 1. Flexibilidade Total - âś… Funciona com qualquer categoria - âś… NĂŁo precisa atualizar cĂłdigo para novas colunas - âś… Adapta-se a mudanças no site ### 2. Manutenção Zero - âś… Novas colunas aparecem automaticamente - âś… Tabelas antigas recebem novas colunas - âś… Tipos de dados corretos ### 3. Dados Completos - âś… Nenhuma informação Ă© perdida - âś… Todas as colunas sĂŁo capturadas - âś… Valores vazios sĂŁo tratados (NULL) --- ## 🔍 Exemplos de Normalização ### Colunas Comuns ```python normalize_column_name("Nome") # → "nome" normalize_column_name("Lvl") # → "lvl" normalize_column_name("NĂvel") # → "nivel" normalize_column_name("Voc") # → "voc" normalize_column_name("MĂŁos") # → "maos" normalize_column_name("Atq") # → "atq" normalize_column_name("Dano Elemental") # → "dano_elemental" normalize_column_name("Def") # → "def" normalize_column_name("Mod. de Defesa") # → "mod_de_defesa" normalize_column_name("BĂ´nus") # → "bonus" normalize_column_name("Slots") # → "slots" normalize_column_name("Tier") # → "tier" normalize_column_name("Peso") # → "peso" normalize_column_name("Dropa de") # → "dropa_de" ``` ### Casos Especiais ```python normalize_column_name("") # → "coluna_sem_nome" normalize_column_name("123abc") # → "col_123abc" normalize_column_name("@#$%") # → "coluna_sem_nome" normalize_column_name("HP/MP") # → "hp_mp" ``` --- ## 🔄 Detecção de Tipo Detalhada ### Exemplos de ConversĂŁo ```python _detect_and_convert_value("150") # → 150 (int) _detect_and_convert_value("10.5") # → 10.5 (float) _detect_and_convert_value("80 oz") # → 80 (int) _detect_and_convert_value("3.50 oz") # → 3.5 (float) _detect_and_convert_value("espada") # → "espada" (text) _detect_and_convert_value("Fire damage") # → "Fire damage" (text) _detect_and_convert_value("-") # → "-" (text) _detect_and_convert_value("") # → None _detect_and_convert_value(" ") # → None ``` ### LĂłgica de Detecção ```python def _detect_and_convert_value(text): if not text or text.strip() == '': return None # 1. Tenta INT int_value = parse_int(text) # "150" → 150, "80 oz" → 80 if int_value is not None: return int_value # 2. Tenta FLOAT float_value = parse_float(text) # "10.5" → 10.5, "3,50" → 3.5 if float_value is not None: return float_value # 3. Retorna TEXT return text.strip() ``` --- ## ⚠️ Casos Especiais ### 1. Coluna Sem Nome (Imagem) ```html