docker
This commit is contained in:
18
Dockerfile
Normal file
18
Dockerfile
Normal 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
1
crontab.txt
Normal file
@ -0,0 +1 @@
|
||||
0 1 * * * python3 /app/main.py >> /var/log/cron.log 2>&1
|
65
docker-compose.yml
Normal file
65
docker-compose.yml
Normal 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
12
init.sql
Normal 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
|
||||
);
|
@ -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()
|
||||
|
Reference in New Issue
Block a user