from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options import time import traceback from dotenv import load_dotenv import os import requests # Charger les variables d'environnement depuis le fichier .env load_dotenv() URL_NVIDIA = os.getenv( "URL", "https://marketplace.nvidia.com/fr-fr/consumer/graphics-cards/?locale=fr-fr&page=1&limit=12&gpu=RTX%205090&manufacturer=NVIDIA&manufacturer_filter=NVIDIA~1" ) N = int(os.getenv("ITER_CYCLES", 1)) WAIT_TIME = int(os.getenv("WAIT_TIME", 3)) RUN_INTERVAL = int(os.getenv("RUN_INTERVAL", 30)) PRINT_BODY = os.getenv("PRINT_BODY", "FALSE").lower() == "true" ERROR_ALERT = os.getenv("ERROR_ALERT", "FALSE").lower() == "true" DISCORD_WEBHOOK_URL = os.getenv("DISCORD_WEBHOOK_URL", "") # Variable pour stocker l'état du stock (évite les notifications répétées) previous_stock_state = False # False = hors stock, True = en stock def send_discord_message(message: str): if not DISCORD_WEBHOOK_URL: print("Aucun webhook Discord défini (DISCORD_WEBHOOK_URL).") return data = {"content": message} try: response = requests.post(DISCORD_WEBHOOK_URL, json=data) if response.status_code >= 400: print(f"Erreur lors de l'envoi du message Discord : {response.text}") else: print("Message Discord envoyé avec succès.") except Exception as e: print(f"Exception lors de l'envoi du message Discord : {e}") def check_stock_button(driver): """ Vérifie si le bouton indiquant une rupture de stock est présent. Retourne True si stock disponible, False sinon. """ try: out_of_stock_buttons = driver.find_elements(By.XPATH, "//button[contains(@class, 'stock-grey-out')]") return not bool(out_of_stock_buttons) except Exception as e: print(f"Erreur lors de la vérification du stock : {e}") return False def checkStockNvidia(): global previous_stock_state chrome_options = Options() chrome_options.add_argument("--headless") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-gpu") chrome_options.add_argument("--disable-notifications") chrome_options.add_argument("--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=chrome_options) for i in range(N): try: driver.get(URL_NVIDIA) time.sleep(WAIT_TIME) # Attente fixe après chargement de la page if PRINT_BODY: print("===== BODY START =====") print(driver.page_source) print("===== BODY END =====") is_available = check_stock_button(driver) if is_available and not previous_stock_state: message = { "title": f"🚀 RTX 5090 FE en stock !", "description": f":point_right: **[Achetez ici](https://marketplace.nvidia.com/fr-fr/consumer/graphics-cards/?locale=fr-fr&page=1&limit=12&gpu=RTX%205090,RTX%205080&manufacturer=NVIDIA)**", "color": 3066993, # Couleur verte "timestamp": time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime()), #"thumbnail": { # "url": "https://www.nvidia.com/content/dam/en-zz/Solutions/geforce/graphic-cards/50-series/rtx-5090/geforce-rtx-5090-learn-more-og-1200x630.jpg" #} } payload = { "content": "@everyone", "username": "Nvidia Bot", "embeds": [message] } send_discord_message(message) previous_stock_state = True # Met à jour l'état du stock elif not is_available: previous_stock_state = False # Remet à zéro pour permettre une future notification except Exception as e: print("ERREUR DURANT UNE VÉRIFICATION :") traceback.print_exc() if ERROR_ALERT: send_discord_message(f"Erreur dans le script :\n```\n{traceback.format_exc()}\n```") driver.quit() if __name__ == "__main__": print(f"Script démarré. Vérification toutes les {RUN_INTERVAL} secondes...") while True: try: checkStockNvidia() except Exception as e: print("ERREUR GLOBALE : ") traceback.print_exc() if ERROR_ALERT: send_discord_message(f"Erreur globale dans le script :\n```\n{traceback.format_exc()}\n```") print(f"Prochaine vérification dans {RUN_INTERVAL} secondes...") time.sleep(RUN_INTERVAL)