mira, tengo esto:

Folder Structure:

ia-web-scraping/
├─ templates/
│   templates/
│   └─ index.html
├─ requirements.txt
├─ app.py
├─ twitter_scraper.py
└─ .gitignore


File Contents:

File: ia-web-scraping/templates/index.html
==========================================
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Análisis de Sentimiento en Twitter</title>
    <script>
        async function analyzeTopic() {
            const topic = document.getElementById("topic").value;
            const response = await fetch("/analyze", {
                method: "POST",
                headers: {"Content-Type": "application/json"},
                body: JSON.stringify({topic})
            });
            const result = await response.json();
            const output = document.getElementById("results");
            output.innerHTML = `<h2>Resumen:</h2><p>${result.summary}</p>`;
        }
    </script>
</head>
<body>
    <h1>Análisis de Sentimiento en Twitter</h1>
    <input type="text" id="topic" placeholder="Ingrese un tema">
    <button onclick="analyzeTopic()">Buscar</button>
    <div id="results"></div>
</body>
</html>



File: ia-web-scraping/requirements.txt
======================================
attrs==24.2.0
blinker==1.9.0
cachetools==5.5.0
certifi==2024.8.30
charset-normalizer==3.4.0
click==8.1.7
Flask==3.1.0
google-api-core==2.23.0
google-auth==2.36.0
google-cloud-language==2.15.1
googleapis-common-protos==1.66.0
grpcio==1.67.1
grpcio-status==1.67.1
h11==0.14.0
idna==3.10
itsdangerous==2.2.0
Jinja2==3.1.4
MarkupSafe==3.0.2
outcome==1.3.0.post0
packaging==24.2
proto-plus==1.25.0
protobuf==5.28.3
pyasn1==0.6.1
pyasn1_modules==0.4.1
PySocks==1.7.1
python-dotenv==1.0.1
requests==2.32.3
rsa==4.9
selenium==4.26.1
sniffio==1.3.1
sortedcontainers==2.4.0
trio==0.27.0
trio-websocket==0.11.1
typing_extensions==4.12.2
urllib3==2.2.3
webdriver-manager==4.0.2
websocket-client==1.8.0
Werkzeug==3.1.3
wsproto==1.2.0


File: ia-web-scraping/app.py
============================
import os
import json
import time
import requests
from flask import Flask, request, jsonify, render_template
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.service import Service
from webdriver_manager.firefox import GeckoDriverManager
from dotenv import load_dotenv

# Cargar variables del archivo .env
load_dotenv()
GOOGLE_API_KEY = os.getenv("AIzaSyCqwn7h-b5ev60lx4dDkJUZTNzpBC3Wbtk")
TWITTER_COOKIES_FILE = "cookies/twitter_cookies.json"

app = Flask(__name__)

# Función para cargar cookies
def load_cookies(driver, filepath):
    with open(filepath, "r") as f:
        cookies = json.load(f)
        for cookie in cookies:
            driver.add_cookie(cookie)

# Inicializar el navegador con cookies cargadas
def init_driver_with_cookies():
    driver = webdriver.Firefox(service=Service(GeckoDriverManager().install()))
    driver.get("https://x.com")
    load_cookies(driver, TWITTER_COOKIES_FILE)
    driver.refresh()
    return driver

# Función para scrapear tweets
def get_tweets(driver, topic):
    search_url = f"https://x.com/search?q={topic}&src=typed_query"
    driver.get(search_url)
    time.sleep(3)
    tweets = [element.text for element in driver.find_elements(By.CSS_SELECTOR, 'article div[lang]')[:10]]
    return tweets

# Función para analizar un resumen de los tweets utilizando la IA
def analyze_tweets_summary(tweets):
    # Unir todos los tweets en un solo texto
    combined_text = "\n".join(tweets)
    
    # URL para el modelo pro-002
    url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro-002:generateContent?key={GOOGLE_API_KEY}"
    
    # Headers y payload para la solicitud
    headers = {
        "Content-Type": "application/json"
    }
    payload = {
        "contents": [
            {
                "parts": [
                    {
                        "text": f"Resumen de los siguientes tweets:\n{combined_text}"
                    }
                ]
            }
        ]
    }

    try:
        # Realizar la solicitud a la API de Google
        response = requests.post(url, headers=headers, json=payload)
        response_data = response.json()
        
        # Verificar si la respuesta tiene el contenido esperado
        if "candidates" in response_data and len(response_data["candidates"]) > 0:
            return response_data["candidates"][0].get("output", "Resumen no disponible.")
        else:
            return "Resumen no disponible."
    
    except Exception as e:
        print(f"Error al generar el resumen: {e}")
        return "Error al generar el resumen."

# Rutas del backend
@app.route("/", methods=["GET"])
def index():
    return render_template("index.html")

@app.route("/analyze", methods=["POST"])
def analyze():
    topic = request.json.get("topic")
    driver = init_driver_with_cookies()
    tweets = get_tweets(driver, topic)
    driver.quit()
    
    # Generar un resumen de todos los tweets
    summary = analyze_tweets_summary(tweets)
    
    return jsonify({"summary": summary})

if __name__ == "__main__":
    app.run(debug=True)



File: ia-web-scraping/twitter_scraper.py
========================================
import os
import time
import json
from dotenv import load_dotenv
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.firefox.service import Service
from webdriver_manager.firefox import GeckoDriverManager

# Cargar las variables del archivo .env
load_dotenv()
TWITTER_USERNAME = os.getenv("TWITTER_USERNAME")
TWITTER_PASSWORD = os.getenv("TWITTER_PASSWORD")

COOKIES_FOLDER = "cookies"
os.makedirs(COOKIES_FOLDER, exist_ok=True)
COOKIES_FILE = os.path.join(COOKIES_FOLDER, "twitter_cookies.json")

def init_driver():
    driver = webdriver.Firefox(service=Service(GeckoDriverManager().install()))
    return driver

def save_cookies(driver, filepath):
    with open(filepath, "w") as f:
        json.dump(driver.get_cookies(), f)

def login_to_twitter(driver):
    driver.get("https://x.com/i/flow/login")
    time.sleep(5)
    driver.find_element(By.NAME, "text").send_keys(TWITTER_USERNAME + Keys.RETURN)
    time.sleep(3)
    driver.find_element(By.NAME, "password").send_keys(TWITTER_PASSWORD + Keys.RETURN)
    time.sleep(5)

if __name__ == "__main__":
    driver = init_driver()
    login_to_twitter(driver)
    save_cookies(driver, COOKIES_FILE)
    driver.quit()
    print("[INFO] Cookies guardadas exitosamente.")



File: ia-web-scraping/.gitignore
================================
Contenido binario o no legible.



pero la ia no me estpa mostrando los twetts, y luego el resumen general:

me dice esto desde el fronted

Resumen:

Resumen no disponible.

quiero probar desde postman como seria? para ver si es el backend o el fronted