init: scripts diversos (crawlers, conversores, scrapers)
This commit is contained in:
195
scraper/consolidate_knowledge.py
Executable file
195
scraper/consolidate_knowledge.py
Executable file
@@ -0,0 +1,195 @@
|
||||
"""
|
||||
consolidate_knowledge.py - Consolidar 118 ficheiros JSON num único ficheiro
|
||||
|
||||
Author: Descomplicar® Crescimento Digital
|
||||
Link: https://descomplicar.pt
|
||||
Copyright: 2025 Descomplicar®
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from typing import Dict, List
|
||||
import statistics
|
||||
|
||||
# Configurações
|
||||
INPUT_DIR = "/media/ealmeida/Dados/GDrive/Cloud/Clientes_360/CTF_Carstuff/KB/Scrapper/sites/knowledge_base_final"
|
||||
OUTPUT_FILE = "/media/ealmeida/Dados/GDrive/Cloud/Clientes_360/CTF_Carstuff/KB/Scrapper/sites/knowledge_base_consolidated.json"
|
||||
|
||||
def load_all_knowledge() -> List[Dict]:
|
||||
"""Carrega todos os ficheiros JSON."""
|
||||
all_knowledge = []
|
||||
input_path = Path(INPUT_DIR)
|
||||
|
||||
json_files = sorted(input_path.glob("knowledge_*.json"))
|
||||
|
||||
print(f"📂 Encontrados {len(json_files)} ficheiros JSON")
|
||||
print("🔄 A carregar...")
|
||||
|
||||
for idx, json_file in enumerate(json_files, 1):
|
||||
try:
|
||||
with open(json_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Adicionar metadata do ficheiro
|
||||
data['_source_file'] = json_file.name
|
||||
data['_id'] = idx
|
||||
|
||||
all_knowledge.append(data)
|
||||
|
||||
if idx % 20 == 0:
|
||||
print(f" ⏳ {idx}/{len(json_files)} carregados...")
|
||||
|
||||
except Exception as e:
|
||||
print(f" ⚠️ Erro em {json_file.name}: {e}")
|
||||
continue
|
||||
|
||||
print(f"✅ {len(all_knowledge)} ficheiros carregados com sucesso")
|
||||
return all_knowledge
|
||||
|
||||
def generate_statistics(knowledge_list: List[Dict]) -> Dict:
|
||||
"""Gera estatísticas sobre o conhecimento consolidado."""
|
||||
stats = {
|
||||
'total_entradas': len(knowledge_list),
|
||||
'total_casos_completos': 0,
|
||||
'categorias': {},
|
||||
'tipos_conteudo': {},
|
||||
'nivel_expertise': {},
|
||||
'materiais_principais': {},
|
||||
'keywords_tecnicas': {},
|
||||
'sites_fonte': {},
|
||||
'aplicabilidades': {}
|
||||
}
|
||||
|
||||
for entry in knowledge_list:
|
||||
# Contar casos completos
|
||||
casos = entry.get('casos_completos', [])
|
||||
stats['total_casos_completos'] += len(casos)
|
||||
|
||||
# Categorias
|
||||
cat = entry.get('categoria_aplicacao', 'desconhecido')
|
||||
stats['categorias'][cat] = stats['categorias'].get(cat, 0) + 1
|
||||
|
||||
# Tipos de conteúdo
|
||||
tipo = entry.get('tipo_conteudo', 'desconhecido')
|
||||
stats['tipos_conteudo'][tipo] = stats['tipos_conteudo'].get(tipo, 0) + 1
|
||||
|
||||
# Nível de expertise
|
||||
nivel = entry.get('nivel_expertise', 'desconhecido')
|
||||
stats['nivel_expertise'][nivel] = stats['nivel_expertise'].get(nivel, 0) + 1
|
||||
|
||||
# Materiais principais
|
||||
materiais = entry.get('materiais_discutidos', {}).get('principais', [])
|
||||
for mat in materiais:
|
||||
stats['materiais_principais'][mat] = stats['materiais_principais'].get(mat, 0) + 1
|
||||
|
||||
# Keywords técnicas
|
||||
keywords = entry.get('keywords_tecnicas', [])
|
||||
for kw in keywords:
|
||||
stats['keywords_tecnicas'][kw] = stats['keywords_tecnicas'].get(kw, 0) + 1
|
||||
|
||||
# Sites fonte
|
||||
source = entry.get('_source_file', 'unknown')
|
||||
site = source.split('_')[1] if '_' in source else 'unknown'
|
||||
stats['sites_fonte'][site] = stats['sites_fonte'].get(site, 0) + 1
|
||||
|
||||
# Aplicabilidades
|
||||
apps = entry.get('aplicabilidade', [])
|
||||
for app in apps:
|
||||
stats['aplicabilidades'][app] = stats['aplicabilidades'].get(app, 0) + 1
|
||||
|
||||
# Ordenar por frequência (top 20)
|
||||
stats['materiais_principais'] = dict(sorted(
|
||||
stats['materiais_principais'].items(),
|
||||
key=lambda x: x[1],
|
||||
reverse=True
|
||||
)[:20])
|
||||
|
||||
stats['keywords_tecnicas'] = dict(sorted(
|
||||
stats['keywords_tecnicas'].items(),
|
||||
key=lambda x: x[1],
|
||||
reverse=True
|
||||
)[:30])
|
||||
|
||||
return stats
|
||||
|
||||
def consolidate_knowledge():
|
||||
"""Função principal de consolidação."""
|
||||
print("═══════════════════════════════════════════════════════════")
|
||||
print(" CTF CARSTUFF - CONSOLIDAÇÃO KNOWLEDGE BASE")
|
||||
print("═══════════════════════════════════════════════════════════")
|
||||
print()
|
||||
|
||||
# Carregar todos os ficheiros
|
||||
all_knowledge = load_all_knowledge()
|
||||
|
||||
if not all_knowledge:
|
||||
print("❌ Nenhum conhecimento carregado!")
|
||||
return
|
||||
|
||||
print()
|
||||
print("📊 A gerar estatísticas...")
|
||||
|
||||
# Gerar estatísticas
|
||||
statistics_data = generate_statistics(all_knowledge)
|
||||
|
||||
# Estrutura final consolidada
|
||||
consolidated = {
|
||||
'metadata': {
|
||||
'created_at': datetime.now().isoformat(),
|
||||
'total_entries': len(all_knowledge),
|
||||
'total_complete_cases': statistics_data['total_casos_completos'],
|
||||
'source_directory': INPUT_DIR,
|
||||
'description': 'Knowledge base consolidada de estofamento automotivo, náutico e aeronáutico',
|
||||
'extraction_criteria': 'Apenas casos completos: Problema → Solução → Resultado'
|
||||
},
|
||||
'statistics': statistics_data,
|
||||
'knowledge_base': all_knowledge
|
||||
}
|
||||
|
||||
# Guardar ficheiro consolidado
|
||||
print(f"💾 A guardar em: {OUTPUT_FILE}")
|
||||
|
||||
output_path = Path(OUTPUT_FILE)
|
||||
with open(output_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(consolidated, f, indent=2, ensure_ascii=False)
|
||||
|
||||
# Verificar tamanho
|
||||
file_size = output_path.stat().st_size / (1024 * 1024) # MB
|
||||
|
||||
print()
|
||||
print("═══════════════════════════════════════════════════════════")
|
||||
print(" CONSOLIDAÇÃO CONCLUÍDA")
|
||||
print("═══════════════════════════════════════════════════════════")
|
||||
print(f"📊 Total de entradas: {len(all_knowledge)}")
|
||||
print(f"📦 Total de casos completos: {statistics_data['total_casos_completos']}")
|
||||
print(f"📁 Tamanho do ficheiro: {file_size:.2f} MB")
|
||||
print(f"💾 Ficheiro: {OUTPUT_FILE}")
|
||||
print()
|
||||
print("📈 ESTATÍSTICAS TOP:")
|
||||
print()
|
||||
print("🏷️ Categorias:")
|
||||
for cat, count in statistics_data['categorias'].items():
|
||||
print(f" - {cat}: {count}")
|
||||
print()
|
||||
print("📋 Tipos de conteúdo:")
|
||||
for tipo, count in statistics_data['tipos_conteudo'].items():
|
||||
print(f" - {tipo}: {count}")
|
||||
print()
|
||||
print("🎓 Nível de expertise:")
|
||||
for nivel, count in statistics_data['nivel_expertise'].items():
|
||||
print(f" - {nivel}: {count}")
|
||||
print()
|
||||
print("🏢 Sites fonte:")
|
||||
for site, count in statistics_data['sites_fonte'].items():
|
||||
print(f" - {site}: {count}")
|
||||
print()
|
||||
print("🔝 Top 10 Materiais:")
|
||||
for idx, (mat, count) in enumerate(list(statistics_data['materiais_principais'].items())[:10], 1):
|
||||
print(f" {idx}. {mat}: {count} menções")
|
||||
print()
|
||||
print("═══════════════════════════════════════════════════════════")
|
||||
|
||||
if __name__ == '__main__':
|
||||
consolidate_knowledge()
|
||||
Reference in New Issue
Block a user