This commit is contained in:
2025-02-04 21:11:33 +01:00
parent e3bee454d9
commit 8f6cf92054
5 changed files with 150 additions and 4 deletions

18
Dockerfile Normal file
View File

@ -0,0 +1,18 @@
# Usa una imagen oficial de Python
FROM python:3.9
# Configurar el directorio de trabajo en el contenedor
WORKDIR /app
# Copiar los archivos de la aplicación al contenedor
COPY app/ /app/
# Instalar dependencias si es necesario (ajusta según tu requerimiento)
RUN pip install mysql-connector-python schedule
# Copiar el archivo de crontab y configurarlo
COPY crontab.txt /etc/cron.d/crontab
RUN chmod 0644 /etc/cron.d/crontab && crontab /etc/cron.d/crontab
# Iniciar cron y ejecutar el script en segundo plano
CMD cron && tail -f /var/log/cron.log

1
crontab.txt Normal file
View File

@ -0,0 +1 @@
0 1 * * * python3 /app/main.py >> /var/log/cron.log 2>&1

65
docker-compose.yml Normal file
View File

@ -0,0 +1,65 @@
version: "3.9"
services:
app:
build: .
container_name: mi_scraper
depends_on:
- mysql
environment:
- MYSQL_HOST=mysql
- MYSQL_USER=root
- MYSQL_PASSWORD=admin123
- MYSQL_DATABASE=scraper_db
volumes:
- ./app:/app
restart: always
networks:
- metanet1
mysql:
image: mysql:8
container_name: mi_mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: admin123
MYSQL_DATABASE: scraper_db
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- metanet1
metabase:
image: metabase/metabase:latest
container_name: metabase
hostname: metabase
volumes:
- /dev/urandom:/dev/random:ro
ports:
- "3000:3000"
environment:
MB_DB_TYPE: mysql
MB_DB_DBNAME: scraper_db
MB_DB_PORT: 3306
MB_DB_USER: root
MB_DB_PASS: admin123
MB_DB_HOST: mysql
networks:
- metanet1
depends_on:
- mysql
healthcheck:
test: curl --fail -I http://localhost:3000/api/health || exit 1
interval: 15s
timeout: 5s
retries: 5
networks:
metanet1:
driver: bridge
volumes:
mysql_data:

12
init.sql Normal file
View File

@ -0,0 +1,12 @@
CREATE DATABASE IF NOT EXISTS scraper_db;
USE scraper_db;
CREATE TABLE IF NOT EXISTS noticias (
id INT AUTO_INCREMENT PRIMARY KEY,
titulo VARCHAR(255) NOT NULL,
contenido TEXT,
autor VARCHAR(255),
fuente VARCHAR(255),
fecha DATETIME,
link TEXT
);

View File

@ -5,6 +5,7 @@ import os
import time
import subprocess
from googlenewsdecoder import gnewsdecoder
import mysql.connector
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
@ -107,6 +108,7 @@ def search_news(query):
}
news_list.append(news_item)
except Exception as e:
print(f"Error al procesar un artículo para '{query}': {e}")
@ -131,15 +133,63 @@ def search_from_keywords_file():
all_news.extend(news_list) # Añadir las noticias encontradas para cada palabra clave
time.sleep(2) # Pausa para evitar bloqueos por demasiadas solicitudes en poco tiempo
# Guardar todas las noticias en un archivo JSON
with open('news_data.json', 'w', encoding='utf-8') as json_file:
json.dump(all_news, json_file, ensure_ascii=False, indent=4)
print("\nTodas las noticias han sido guardadas en 'news_data.json'.")
# Guardar todas las noticias en la base de datos
insertar_datos(all_news,"noticias")
except FileNotFoundError:
print("No se encontró el archivo 'keywords.txt'.")
except Exception as e:
print(f"Error al leer el archivo 'keywords.txt': {e}")
def insertar_datos(lista_objetos, tabla):
"""
Inserta una lista de diccionarios en una tabla de MySQL utilizando variables de entorno de Docker.
:param lista_objetos: Lista de diccionarios con los datos a insertar.
:param tabla: Nombre de la tabla en la base de datos.
"""
if not lista_objetos:
print("Lista vacía, no hay datos para insertar.")
return
# Obtener configuración de MySQL desde variables de entorno
db_config = {
"host": os.getenv("MYSQL_HOST", "localhost"),
"user": os.getenv("MYSQL_USER", "root"),
"password": os.getenv("MYSQL_PASSWORD", ""),
"database": os.getenv("MYSQL_DATABASE", "test"),
}
# Obtener las columnas de la primera entrada
columnas = lista_objetos[0].keys()
columnas_str = ", ".join(columnas)
valores_str = ", ".join(["%s"] * len(columnas))
# Crear la consulta SQL
query = f"INSERT INTO {tabla} ({columnas_str}) VALUES ({valores_str})"
# Convertir los datos en tuplas
valores = [tuple(obj[col] for col in columnas) for obj in lista_objetos]
try:
# Conectar a la base de datos
conexion = mysql.connector.connect(**db_config)
cursor = conexion.cursor()
# Ejecutar la inserción de múltiples filas
cursor.executemany(query, valores)
conexion.commit()
print(f"{cursor.rowcount} registros insertados correctamente en {tabla}.")
except mysql.connector.Error as err:
print(f"Error: {err}")
conexion.rollback()
finally:
cursor.close()
conexion.close()
# Ejecutar la búsqueda desde el archivo
search_from_keywords_file()