- 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>
8.5 KiB
Scraper de Imágenes + Analizador Qwen3-VL — Contexto técnico FLUJOS
Fecha: 2026-04-21
Directorio: FLUJOS_DATOS/IMAGENES/
Entorno: FLUJOS_DATOS/myenv/ (Python 3.11, venv)
Componentes del módulo
FLUJOS_DATOS/IMAGENES/
├── wikipedia_image_scraper.py # Descarga imágenes de Wikipedia por tema
├── image_analyzer.py # Analiza imágenes con Qwen3-VL-8B
├── image_comparator.py # Compara imágenes (similaridad visual)
├── mongo_helper.py # Utilidades MongoDB para este módulo
├── pipeline_imagenes.py # Orquestador del módulo (flags CLI)
├── requirements_imagenes.txt # Dependencias del módulo
├── model_cache/ # Modelo Qwen descargado (~16 GB) — en .gitignore
└── output/
└── wiki_images/ # Imágenes descargadas — en .gitignore
├── cambio_climático/
├── geopolítica_conflictos/
├── seguridad_internacional_espionaje/
└── ...
Parte 1: wikipedia_image_scraper.py
Qué hace
Descarga imágenes de Wikipedia por tema usando la Wikimedia REST API. Para cada tema de FLUJOS busca artículos relacionados, extrae las imágenes de cada artículo y las descarga filtrando iconos/logos pequeños.
Temas de FLUJOS que se scrapean (TEMAS_FLUJOS)
TEMAS_FLUJOS = [
"cambio climático",
"geopolítica conflictos",
"seguridad internacional espionaje",
"libertad de prensa periodismo",
"corporaciones poder económico",
"populismo extremismo",
"desinformación redes sociales",
"privacidad vigilancia masiva",
"biodiversidad medioambiente",
"inteligencia artificial tecnología",
]
Filtros de calidad (imágenes que se descartan)
MIN_WIDTH = 200 # pixels
MIN_HEIGHT = 200 # pixels
MIN_BYTES = 20_000 # 20 KB mínimo
SKIP_PATTERNS = [
"flag_", "Flag_", "icon", "Icon", "logo", "Logo",
"symbol", "Symbol", "coat_of_arms", "commons-logo",
"wiki", "Wiki", "question_mark", "edit-", "nuvola",
"Nuvola", "pictogram", "OOjs", "Ambox", "Portal-", "Disambig",
]
VALID_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp"}
Flujo interno
buscar_articulos(tema, lang='es')
└── GET https://es.wikipedia.org/w/api.php?action=query&list=search&srsearch={tema}
└── para cada artículo:
get_article_images(titulo)
└── GET https://es.wikipedia.org/w/api.php?action=query&prop=images
└── para cada imagen:
get_image_info(filename) → Wikimedia API
└── descarga si pasa filtros
└── guarda en output/wiki_images/{tema_slug}/
└── upsert en MongoDB imagenes_wiki
Deduplicación
Upsert por archivo (nombre del fichero) en MongoDB imagenes_wiki. Si el fichero ya existe en disco, se salta la descarga.
Uso CLI
# Scrape de todos los temas FLUJOS, max 20 imgs/tema, con MongoDB
python wikipedia_image_scraper.py --flujos --max 20 --mongo
# Scrape de un tema concreto
python wikipedia_image_scraper.py --tema "cambio climático" --max 30 --mongo
# Con idioma inglés
python wikipedia_image_scraper.py --tema "climate change" --lang en --max 40
Documento MongoDB generado (colección imagenes_wiki)
{
"archivo": "cambio_climático_003.jpg",
"image_path": "/var/www/theflows.net/flujos/FLUJOS_DATOS/IMAGENES/output/wiki_images/cambio_climático/cambio_climático_003.jpg",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/...",
"tema": "cambio climático",
"subtema": "derretimiento glaciar ártico",
"descripcion_wiki": "Glaciar en retroceso en el Ártico, 2019",
"articulo_titulo": "Cambio climático en el Ártico",
"fecha": ISODate("2026-04-21")
}
Parte 2: image_analyzer.py (Qwen3-VL-8B)
Modelo usado
Qwen/Qwen2.5-VL-7B-Instruct (HuggingFace)
- Tamaño: ~16 GB en disco (bfloat16)
- Inferencia: CPU (sin GPU disponible actualmente)
- RAM necesaria: ~16–18 GB para el modelo + ~2 GB por batch de 4 imágenes
- Cache local:
IMAGENES/model_cache/
El servidor tiene 64 GB RAM, por lo que cabe sin problema. En GPU (A100/RTX 3090+) sería 10–50x más rápido.
Carga del modelo
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
import torch
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
"Qwen/Qwen2.5-VL-7B-Instruct",
torch_dtype=torch.bfloat16, # mitad de RAM vs float32
device_map="cpu",
cache_dir=str(IMAGENES_DIR / "model_cache"),
)
processor = AutoProcessor.from_pretrained(
"Qwen/Qwen2.5-VL-7B-Instruct",
cache_dir=str(IMAGENES_DIR / "model_cache"),
)
Prompt de análisis
PROMPT = """Analiza esta imagen y proporciona:
1. Una descripción concisa del contenido principal (máx. 2 frases).
2. El tema principal (elige uno): cambio climático, conflicto armado, economía, política, tecnología, sociedad, otro.
3. Lista de 3-5 palabras clave relevantes.
Formato de respuesta:
DESCRIPCIÓN: [descripción]
TEMA: [tema]
PALABRAS CLAVE: [kw1, kw2, kw3]"""
Procesamiento por batch
def analyze_batch(image_paths: list[Path]) -> list[dict]:
"""Procesa hasta 4 imágenes por llamada al modelo."""
batch_size=4 por defecto. Cada batch ocupa ~2 GB RAM adicionales.
Resume automático
Antes de analizar, verifica qué imágenes ya están en MongoDB imagenes:
def get_already_analyzed() -> set[str]:
"""Devuelve set de nombres de archivo ya en la colección imagenes."""
return {doc['archivo'] for doc in db['imagenes'].find({}, {'archivo': 1})}
Solo procesa imágenes no presentes en la BD.
Priorización de imágenes
def get_known_article_titles() -> set[str]:
"""Títulos de artículos presentes en wikipedia/noticias."""
# Prioriza imágenes cuyo tema coincide con artículos existentes
Las imágenes de temas con más documentos de texto en la BD se procesan primero, para maximizar la probabilidad de que los nodos imagen queden conectados por comparaciones.
Documento MongoDB generado (colección imagenes)
{
"archivo": "cambio_climático_003.jpg",
"image_path": "/var/www/.../output/wiki_images/cambio_climático/cambio_climático_003.jpg",
"tema": "cambio climático",
"subtema": "calentamiento global",
"texto": "Imagen satelital del retroceso del glaciar ártico entre 1990 y 2023. Se observa una reducción significativa de la capa de hielo.",
"keywords": ["glaciar", "ártico", "deshielo", "calentamiento", "satélite"],
"fecha": ISODate("2026-04-21")
}
Parte 3: pipeline_imagenes.py (orquestador)
Flags CLI
python pipeline_imagenes.py --scrape # solo scraping de imágenes
python pipeline_imagenes.py --analizar # solo análisis Qwen
python pipeline_imagenes.py --mongo # escribe resultados en MongoDB
python pipeline_imagenes.py --solo-json # escribe JSON local en vez de Mongo
python pipeline_imagenes.py --analizar --carpeta /ruta/custom --mongo
Integración en el pipeline maestro
El pipeline_maestro.py lo llama así:
Fase 1 (scraping):
python wikipedia_image_scraper.py --flujos --max 20 --mongo
Fase 2 (análisis):
python pipeline_imagenes.py --analizar \
--carpeta FLUJOS_DATOS/IMAGENES/output/wiki_images \
--mongo
Dependencias Python (requirements_imagenes.txt)
transformers>=4.45
torch>=2.1
qwen-vl-utils
Pillow
requests
pymongo
scikit-learn
python-dotenv
Instalación en el venv:
/var/www/theflows.net/flujos/FLUJOS_DATOS/myenv/bin/python3 -m pip install -r requirements_imagenes.txt
Estado actual (2026-04-21)
- Imágenes en disco: ~155 imágenes en
output/wiki_images/(10 temas × ~15 imgs) - Imágenes en
imagenes_wiki(MongoDB): ~150 docs - Imágenes analizadas con Qwen en
imagenes(MongoDB): proceso en curso / pendiente de primera ejecución completa - El modelo Qwen se descarga automáticamente la primera vez que se llama (~16 GB, puede tardar 30–60 min)
Pendiente / mejoras futuras
- Conectar nodos imagen a la colección
comparaciones(requiere embeddings de imagen o comparación texto-descripción) - Activar GPU cuando esté disponible (cambiar
device_map="cpu"→"cuda") - Aumentar
--maxa 50+ imágenes por tema una vez el análisis esté validado - Añadir soporte para imágenes de noticias (no solo Wikipedia)