- docs/ → INFO/DOCS/CONTEXT/ (documentación técnica en markdown) - FLUJOS/DOCS/ + FLUJOS_DATOS/DOCS/ → INFO/DOCS/ (txts de arquitectura) - POCS/ → INFO/POCS/ (pruebas de concepto) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7 KiB
Scraper de Wikipedia — Contexto técnico FLUJOS
Fecha: 2026-04-21
Archivo: FLUJOS_DATOS/WIKIPEDIA/main.py
Utilidades: FLUJOS_DATOS/WIKIPEDIA/wikipedia_utils.py
Entorno: FLUJOS_DATOS/myenv/ (Python 3.11, venv)
Qué hace
Descarga artículos de Wikipedia en español organizados por temas de FLUJOS, los limpia, tokeniza con BERT y los guarda en disco (.txt) y MongoDB (wikipedia).
Temas y palabras clave
El scraper itera sobre un diccionario de temas con listas de keywords. Para cada keyword hace una búsqueda en la Wikipedia API y descarga los artículos encontrados.
temas = {
"inteligencia y seguridad": [
"inteligencia", "seguridad", "espionaje", "ciberseguridad", "NSA", "FBI", "CIA",
"contraterrorismo", "criptografía", "vigilancia", "hackeo", "ransomware", ...
],
"guerras": [
"guerra", "conflicto", "batalla", "militar", "guerra civil", "intervención militar",
"fuerzas armadas", "ejército", "terrorismo", "crímenes de guerra", ...
],
"corporaciones": [
"empresa", "multinacionales", "mercado bursátil", "BlackRock", "Vanguard",
"fusiones", "adquisiciones", "venture capital", "evasión fiscal", ...
],
"demografía": [
"población", "migración", "natalidad", "urbanización", "refugiados",
"desigualdad", "pobreza", "pandemia", ...
],
"cambio climático": [
"cambio climático", "calentamiento global", "energías renovables",
"deforestación", "emisiones de carbono", "acuerdo de París", ...
],
"organizaciones internacionales": [
"OTAN", "BRICS", "ONU", "Unión Europea", "FMI", "Banco Mundial", ...
],
"gobiernos autoritarios": [
"dictadura", "autoritario", "represión política", "censura", "prisioneros políticos", ...
],
}
Cada tema tiene entre 50 y 100 palabras clave. En total son ~500 keywords → cada una genera hasta 50 artículos = potencial de ~25.000 artículos.
Flujo de scraping
para cada (tema, palabras_clave):
para cada palabra_clave:
buscar_articulos(palabra_clave, max_articulos=50, offset=0)
└── GET https://es.wikipedia.org/w/api.php
action=query, list=search, srsearch={keyword}
para cada titulo encontrado:
if titulo not in titulos_descargados:
contenido = obtener_contenido_wikipedia(titulo)
└── GET https://es.wikipedia.org/w/api.php
action=query, prop=revisions, rvprop=content
guardar en articulos_wikipedia/{titulo_limpio}.txt
titulos_descargados.add(titulo)
offset += 50 # paginación
time.sleep(1) # cortesía hacia la API
Límite de tamaño: Para cuando articulos_wikipedia/ supera 100 GB (en la práctica nunca se ha alcanzado).
Limpieza de texto
def limpiar_texto(texto):
texto = texto.lower()
texto = re.sub(r'[^\w\s]', '', texto) # elimina puntuación
palabras = texto.split()
palabras_limpias = [p for p in palabras if p not in stopwords]
return ' '.join(palabras_limpias)
Stopwords: lista manual en español (~200 palabras). No usa NLTK en este módulo (sí en pipeline_completo.py).
Tokenización BERT
from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('dccuchile/bert-base-spanish-wwm-cased')
def TOKENIZER():
archivos = os.listdir('articulos_wikipedia')
for archivo in archivos:
contenido = open(f'articulos_wikipedia/{archivo}').read()
tokens_ids = tokenizer.encode(contenido, add_special_tokens=False)
with open(f'articulos_tokenizados/{archivo}', 'w') as f:
f.write(' '.join(map(str, tokens_ids)))
- Modelo BERT:
dccuchile/bert-base-spanish-wwm-cased(BERT en español de la U. de Chile) - Truncación: 512 tokens máximo por documento
- Output: archivo
.txtcon IDs numéricos separados por espacios
Limpiar nombre de fichero
def limpiar_nombre_archivo(nombre):
nombre = re.sub(r'[\\/*?:"<>|]', "_", nombre)
return nombre
# Ejemplo: "Guerra_del_Golfo_(1990)" → "Guerra_del_Golfo__1990_"
El nombre del fichero es el título del artículo de Wikipedia limpiado. Es también el archivo en MongoDB (clave de dedup).
Asignación de tema y subtema
Esta lógica vive en pipeline_completo.py::asignar_tema_y_subtema(), no en el scraper. El scraper solo guarda texto; el tokenizador/comparador asigna el tema.
tematicas = {
'inteligencia y seguridad': ['inteligencia', 'ciberseguridad', 'espionaje', ...],
'cambio climático': ['cambio climático', 'desastres naturales', ...],
'guerra global': ['conflictos internacionales', 'guerras civiles', ...],
'demografía y sociedad': ['sobrepoblación', 'migraciones', ...],
'economía y corporaciones': ['economía global', 'corporaciones multinacionales', ...],
}
# Si ningún keyword coincide: tema='otros', subtema='general'
Documento MongoDB generado (colección wikipedia)
{
"_id": ObjectId,
"archivo": "Guerra_del_Golfo.txt",
"tema": "guerra global",
"subtema": "conflictos internacionales",
"texto": "La Guerra del Golfo fue un conflicto armado...",
"fecha": null // Wikipedia no suele tener fecha de publicación clara
}
La inserción usa upsert por archivo para deduplicar.
Almacenamiento en disco (ignorado por git)
FLUJOS_DATOS/WIKIPEDIA/
├── articulos_wikipedia/ # .gitignore — txt en español por artículo
├── articulos_tokenizados/ # .gitignore — IDs BERT por artículo
├── main.py
├── wikipedia_utils.py
└── docs.txt
Ejecución dentro del pipeline maestro
pipeline_maestro.py Fase 1 llama:
/var/www/theflows.net/flujos/FLUJOS_DATOS/myenv/bin/python3 \
FLUJOS_DATOS/WIKIPEDIA/main.py
Desde el directorio FLUJOS_DATOS/WIKIPEDIA/ para que las rutas relativas (articulos_wikipedia/) funcionen.
Limitaciones conocidas
- Sin fecha en artículos Wikipedia — El scraper no extrae la fecha de revisión. El campo
fechaqueda ennullo vacío en Mongo, lo que rompe los filtros de fecha en la API. - Nombres duplicados potenciales — Artículos con títulos similares generan el mismo nombre de fichero después de la limpieza.
- No hay control de idioma — Si un keyword es un acrónimo (NSA, CIA), puede devolver artículos en inglés mezclados con los españoles.
- Tokenización trunca a 512 tokens — Artículos largos pierden la segunda mitad para el cálculo de similitud.
- Sin rate limiting robusta — Solo
time.sleep(1)entre keywords, pero la Wikipedia API tiene un límite de 200 req/s por IP (raramente alcanzado).
Dependencias
transformers>=4.45 (BertTokenizer)
tqdm
requests
pymongo
BERT (dccuchile/bert-base-spanish-wwm-cased) se descarga automáticamente en el primer uso (~500 MB, se cachea en ~/.cache/huggingface/).