149 lines
5.8 KiB
Python
149 lines
5.8 KiB
Python
import requests
|
|
from bs4 import BeautifulSoup
|
|
import json
|
|
import os
|
|
import time
|
|
import subprocess
|
|
from googlenewsdecoder import gnewsdecoder
|
|
from iacorrector import is_security_related # Importa la función desde iacorrector.py
|
|
|
|
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"
|
|
}
|
|
|
|
def get_author_from_script(url):
|
|
"""
|
|
Llama a autorsearcher.py con la URL de la noticia y devuelve el autor encontrado.
|
|
"""
|
|
try:
|
|
result = subprocess.run(["python", "autorsearcher.py", url], capture_output=True, text=True)
|
|
author = result.stdout.strip()
|
|
return author if author else "Desconocido"
|
|
except Exception as e:
|
|
print(f"Error al obtener el autor para {url}: {e}")
|
|
return "Desconocido"
|
|
|
|
def get_url_from_google_news(url):
|
|
interval_time = 1
|
|
try:
|
|
decoded_url = gnewsdecoder(url, interval=interval_time)
|
|
|
|
if decoded_url.get("status"):
|
|
return decoded_url["decoded_url"]
|
|
else:
|
|
return "N/C"
|
|
except Exception as e:
|
|
print(f"Error occurred: {e}")
|
|
|
|
def get_article_content(url):
|
|
"""
|
|
Extrae el texto principal del artículo desde la URL final.
|
|
"""
|
|
try:
|
|
response = requests.get(url, headers=HEADERS)
|
|
if response.status_code != 200:
|
|
print(f"Error al acceder a {url}: Código {response.status_code}")
|
|
return "No se pudo obtener el contenido"
|
|
|
|
soup = BeautifulSoup(response.text, "html.parser")
|
|
|
|
# Buscar los elementos más comunes donde se almacena el contenido del artículo
|
|
possible_containers = [
|
|
soup.find("article"), # Etiqueta <article> (común en blogs y periódicos)
|
|
soup.find("div", class_="post-content"), # Clases comunes en WordPress
|
|
soup.find("div", class_="entry-content"),
|
|
soup.find("div", class_="content"),
|
|
soup.find("div", id="article-body")
|
|
]
|
|
|
|
for container in possible_containers:
|
|
if container:
|
|
paragraphs = container.find_all("p")
|
|
article_text = "\n".join(p.get_text(strip=True) for p in paragraphs)
|
|
return article_text if article_text else "No se encontró contenido relevante"
|
|
|
|
return "No se encontró contenido relevante"
|
|
|
|
except Exception as e:
|
|
print(f"Error al extraer contenido de {url}: {e}")
|
|
return "Error al extraer contenido"
|
|
|
|
def search_news(query):
|
|
"""
|
|
Busca noticias relacionadas con una palabra clave en Google News.
|
|
"""
|
|
base_url = f"https://news.google.com/rss/search?q={query.replace(' ', '+')}&hl=es&gl=ES&ceid=ES%3Aes"
|
|
response = requests.get(base_url, headers=HEADERS)
|
|
|
|
if response.status_code != 200:
|
|
print(f"Error al acceder a la página para la consulta '{query}': {response.status_code}")
|
|
return []
|
|
|
|
soup = BeautifulSoup(response.content, 'xml')
|
|
articles = soup.find_all("item")
|
|
news_list = []
|
|
|
|
for article in articles[:30]: # Limitar a los primeros 30 artículos
|
|
try:
|
|
title = article.title.get_text(strip=True)
|
|
content = article.description.get_text(strip=True) if article.description else "Sin descripción"
|
|
link = article.link.get_text(strip=True)
|
|
source_info = article.source.get_text(strip=True) if article.source else "Desconocido"
|
|
date = article.pubDate.get_text(strip=True) if article.pubDate else "Fecha no disponible"
|
|
|
|
# Obtener la URL final del artículo
|
|
final_url = get_url_from_google_news(link)
|
|
|
|
# Obtener el autor usando autorsearcher.py
|
|
author = get_author_from_script(final_url)
|
|
content = get_article_content(final_url)
|
|
|
|
# Verificar si el artículo es válido usando iacorrector
|
|
if is_security_related(content): # Solo si el artículo es válido
|
|
news_item = {
|
|
"titulo": title,
|
|
"contenido": content,
|
|
"autor": author,
|
|
"fuente": source_info,
|
|
"fecha": date,
|
|
"link": final_url # Guardamos la URL final en lugar de la de Google News
|
|
}
|
|
news_list.append(news_item)
|
|
|
|
except Exception as e:
|
|
print(f"Error al procesar un artículo para '{query}': {e}")
|
|
|
|
return news_list
|
|
|
|
def search_from_keywords_file():
|
|
"""
|
|
Lee palabras clave del archivo 'keywords.txt' y realiza búsquedas para cada una.
|
|
"""
|
|
all_news = [] # Lista para almacenar todas las noticias recolectadas
|
|
|
|
try:
|
|
with open("keywords.txt", "r", encoding="utf-8") as file:
|
|
keywords = file.readlines()
|
|
|
|
# Eliminar posibles saltos de línea y espacios extra
|
|
keywords = [keyword.strip() for keyword in keywords]
|
|
|
|
for keyword in keywords:
|
|
print(f"\nBuscando noticias sobre: {keyword}")
|
|
news_list = search_news(keyword)
|
|
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'.")
|
|
|
|
except FileNotFoundError:
|
|
print("No se encontró el archivo 'keywords.txt'.")
|
|
except Exception as e:
|
|
print(f"Error al leer el archivo 'keywords.txt': {e}")
|
|
|
|
# Ejecutar la búsqueda desde el archivo
|
|
search_from_keywords_file()
|