From bf12f2c6f16e3840905c09b452ef9ca109ca611d Mon Sep 17 00:00:00 2001 From: Evandro Fonseca Junior Date: Wed, 29 Oct 2025 23:44:40 -0300 Subject: [PATCH] scrapping --- iconScript/README.md | 0 iconScript/explore_structure.py | 227 +++++++++++++++++++ iconScript/main.py | 0 iconScript/requirements.txt | 3 + iconScript/scrapy.cfg | 6 + iconScript/tibiawiki/__init__.py | 2 + iconScript/tibiawiki/items.py | 0 iconScript/tibiawiki/middlewares.py | 0 iconScript/tibiawiki/pipelines.py | 0 iconScript/tibiawiki/settings.py | 0 iconScript/tibiawiki/spiders/__init__.py | 2 + iconScript/tibiawiki/spiders/items_spider.py | 0 iconScript/tibiawiki/utils.py | 0 pnpm-workspace.yaml | 2 + 14 files changed, 242 insertions(+) create mode 100644 iconScript/README.md create mode 100644 iconScript/explore_structure.py create mode 100644 iconScript/main.py create mode 100644 iconScript/requirements.txt create mode 100644 iconScript/scrapy.cfg create mode 100644 iconScript/tibiawiki/__init__.py create mode 100644 iconScript/tibiawiki/items.py create mode 100644 iconScript/tibiawiki/middlewares.py create mode 100644 iconScript/tibiawiki/pipelines.py create mode 100644 iconScript/tibiawiki/settings.py create mode 100644 iconScript/tibiawiki/spiders/__init__.py create mode 100644 iconScript/tibiawiki/spiders/items_spider.py create mode 100644 iconScript/tibiawiki/utils.py create mode 100644 pnpm-workspace.yaml diff --git a/iconScript/README.md b/iconScript/README.md new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/explore_structure.py b/iconScript/explore_structure.py new file mode 100644 index 0000000..80312e9 --- /dev/null +++ b/iconScript/explore_structure.py @@ -0,0 +1,227 @@ +""" +Script de análise exploratória para mapear estrutura do TibiaWiki +Executa uma análise inicial da página de itens e suas categorias +""" +import requests +from bs4 import BeautifulSoup +from urllib.parse import urljoin +import json + +BASE_URL = "https://www.tibiawiki.com.br" +ITEMS_URL = f"{BASE_URL}/wiki/Itens" + + +def fetch_page(url): + """Busca o conteúdo HTML de uma página""" + headers = { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', + 'Accept-Language': 'pt-BR,pt;q=0.9,en-US;q=0.8,en;q=0.7', + 'Accept-Encoding': 'gzip, deflate, br', + 'Connection': 'keep-alive', + 'Upgrade-Insecure-Requests': '1' + } + response = requests.get(url, headers=headers, timeout=30) + response.raise_for_status() + return response.text + + +def analyze_items_page(): + """Analisa a página principal de itens""" + print("=" * 80) + print("ANÁLISE DA PÁGINA PRINCIPAL: /wiki/Itens") + print("=" * 80) + + html = fetch_page(ITEMS_URL) + soup = BeautifulSoup(html, 'html.parser') + + # Encontrar todas as imagens com links (categorias) + categories = {} + + # Procurar por links de categorias com imagens + # Geralmente estão em tabelas ou listas com imagens .gif + images_with_links = soup.find_all('a', href=True) + + for link in images_with_links: + img = link.find('img') + if img and img.get('alt'): + item_name = img.get('alt', '').replace('.gif', '') + href = link.get('href') + + # Verificar se é um link válido para categoria + if href and '/wiki/' in href and item_name: + full_url = urljoin(BASE_URL, href) + + # Procurar texto próximo que indique a categoria + parent = link.parent + text_content = parent.get_text(strip=True) if parent else "" + + # Guardar informação + if item_name not in categories: + categories[item_name] = { + 'url': full_url, + 'context': text_content[:100] # Primeiros 100 caracteres + } + + # Procurar especificamente por categorias mencionadas + # Capacetes, Armaduras, Escudos, Calças, etc. + category_keywords = [ + 'Capacetes', 'Armaduras', 'Escudos', 'Calças', 'Spellbooks', + 'Botas', 'Aljavas', 'Machados', 'Clavas', 'Espadas', 'Rods', + 'Wands', 'Distância', 'Munição', 'Punhos', 'Livros', 'Decorações', + 'Troféus', 'Comidas', 'Líquidos', 'Plantas', 'Amuletos', 'Colares', + 'Anéis', 'Chaves', 'Ferramentas', 'Recipientes' + ] + + found_categories = {} + + # Procurar links que contenham essas palavras-chave + all_links = soup.find_all('a', href=True) + for link in all_links: + link_text = link.get_text(strip=True) + href = link.get('href') + + # Verificar se o texto do link corresponde a uma categoria + for keyword in category_keywords: + if keyword.lower() in link_text.lower() and '/wiki/' in href: + full_url = urljoin(BASE_URL, href) + if keyword not in found_categories: + found_categories[keyword] = full_url + print(f"\n✓ Categoria encontrada: {keyword}") + print(f" URL: {full_url}") + + print(f"\n\nTotal de categorias identificadas: {len(found_categories)}") + + # Salvar mapeamento + with open('iconScript/categories_mapping.json', 'w', encoding='utf-8') as f: + json.dump(found_categories, f, ensure_ascii=False, indent=2) + + print("\n✓ Mapeamento salvo em categories_mapping.json") + + return found_categories + + +def analyze_category_page(category_name, url, max_items=5): + """Analisa a estrutura de uma página de categoria específica""" + print("\n" + "=" * 80) + print(f"ANÁLISE DA CATEGORIA: {category_name}") + print("=" * 80) + print(f"URL: {url}\n") + + try: + html = fetch_page(url) + soup = BeautifulSoup(html, 'html.parser') + + # Procurar tabelas + tables = soup.find_all('table') + print(f"Tabelas encontradas: {len(tables)}") + + # Analisar a primeira tabela com classe 'wikitable' (padrão do MediaWiki) + wikitable = soup.find('table', class_='wikitable') + + if not wikitable: + # Tentar qualquer tabela + wikitable = tables[0] if tables else None + + if wikitable: + # Extrair cabeçalhos + headers = [] + header_row = wikitable.find('tr') + if header_row: + ths = header_row.find_all(['th', 'td']) + headers = [th.get_text(strip=True) for th in ths] + + print(f"\nColunas da tabela ({len(headers)}):") + for i, header in enumerate(headers, 1): + print(f" {i}. {header}") + + # Analisar algumas linhas de exemplo + rows = wikitable.find_all('tr')[1:] # Pular cabeçalho + print(f"\nLinhas de dados encontradas: {len(rows)}") + + if rows: + print(f"\nExemplo de {min(max_items, len(rows))} itens:") + + for i, row in enumerate(rows[:max_items], 1): + cells = row.find_all(['td', 'th']) + print(f"\n Item {i}:") + + for j, cell in enumerate(cells): + if j < len(headers): + # Verificar se tem imagem + img = cell.find('img') + if img: + img_src = img.get('src', '') + print(f" {headers[j]}: [IMAGEM: {img_src}]") + + # Pegar texto + text = cell.get_text(strip=True) + if text: + print(f" {headers[j]}: {text}") + + return { + 'columns': headers, + 'row_count': len(rows), + 'has_images': bool(wikitable.find('img')) + } + else: + print("⚠ Nenhuma tabela encontrada nesta categoria") + return None + + except Exception as e: + print(f"✗ Erro ao analisar categoria: {e}") + return None + + +def main(): + """Função principal de análise""" + print("\n" + "=" * 80) + print("INICIANDO ANÁLISE EXPLORATÓRIA DO TIBIAWIKI") + print("=" * 80 + "\n") + + # Analisar página principal + categories = analyze_items_page() + + # Analisar algumas categorias como exemplo + sample_categories = ['Capacetes', 'Armaduras', 'Espadas'] + + all_columns = set() + category_structures = {} + + for cat_name in sample_categories: + if cat_name in categories: + result = analyze_category_page(cat_name, categories[cat_name]) + if result: + category_structures[cat_name] = result + all_columns.update(result['columns']) + + # Resumo de todas as colunas encontradas + print("\n" + "=" * 80) + print("RESUMO: TODAS AS COLUNAS IDENTIFICADAS") + print("=" * 80) + print(f"\nTotal de colunas únicas: {len(all_columns)}") + for col in sorted(all_columns): + print(f" - {col}") + + # Salvar estrutura completa + with open('iconScript/structure_analysis.json', 'w', encoding='utf-8') as f: + json.dump({ + 'all_columns': list(all_columns), + 'category_structures': category_structures, + 'categories': categories + }, f, ensure_ascii=False, indent=2) + + print("\n✓ Análise completa salva em structure_analysis.json") + + print("\n" + "=" * 80) + print("ANÁLISE CONCLUÍDA") + print("=" * 80) + print("\nPróximos passos:") + print("1. Revisar categories_mapping.json para ver todas as categorias") + print("2. Revisar structure_analysis.json para ver estrutura das tabelas") + print("3. Definir schema SQLite unificado baseado nas colunas identificadas") + + +if __name__ == '__main__': + main() + diff --git a/iconScript/main.py b/iconScript/main.py new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/requirements.txt b/iconScript/requirements.txt new file mode 100644 index 0000000..5490526 --- /dev/null +++ b/iconScript/requirements.txt @@ -0,0 +1,3 @@ +scrapy>=2.11.0 +pillow>=10.0.0 + diff --git a/iconScript/scrapy.cfg b/iconScript/scrapy.cfg new file mode 100644 index 0000000..2e979fa --- /dev/null +++ b/iconScript/scrapy.cfg @@ -0,0 +1,6 @@ +[settings] +default = tibiawiki.settings + +[deploy] +project = tibiawiki + diff --git a/iconScript/tibiawiki/__init__.py b/iconScript/tibiawiki/__init__.py new file mode 100644 index 0000000..49b1494 --- /dev/null +++ b/iconScript/tibiawiki/__init__.py @@ -0,0 +1,2 @@ +# TibiaWiki Scraper Project + diff --git a/iconScript/tibiawiki/items.py b/iconScript/tibiawiki/items.py new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/tibiawiki/middlewares.py b/iconScript/tibiawiki/middlewares.py new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/tibiawiki/pipelines.py b/iconScript/tibiawiki/pipelines.py new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/tibiawiki/settings.py b/iconScript/tibiawiki/settings.py new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/tibiawiki/spiders/__init__.py b/iconScript/tibiawiki/spiders/__init__.py new file mode 100644 index 0000000..2e7ed1f --- /dev/null +++ b/iconScript/tibiawiki/spiders/__init__.py @@ -0,0 +1,2 @@ +# Spiders module + diff --git a/iconScript/tibiawiki/spiders/items_spider.py b/iconScript/tibiawiki/spiders/items_spider.py new file mode 100644 index 0000000..e69de29 diff --git a/iconScript/tibiawiki/utils.py b/iconScript/tibiawiki/utils.py new file mode 100644 index 0000000..e69de29 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..e6654d6 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +onlyBuiltDependencies: + - sharp