import os, json, logging, requests, re, time from datetime import datetime from flask import Flask, render_template, redirect, url_for from bs4 import BeautifulSoup app = Flask(__name__) logging.basicConfig(level=logging.INFO, format='%(message)s') logger = logging.getLogger("Cosmo_Scraper") CACHE_FILE = "/data/movies_cache.json" BASE_URL = "https://www.american-cosmograph.fr" HEADERS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'} def get_today_id(): """Génère l'ID du bloc jour, ex: 'seance-2026-02-19'""" return f"seance-{datetime.now().strftime('%Y-%m-%d')}" def scrape_cosmo_only(): url_horaires = f"{BASE_URL}/les-horaires.html" target_id = get_today_id() logger.info(f"\n[DEBUG] --- DÉBUT SCRAPING AMERICAN COSMOGRAPH ---") logger.info(f"[DEBUG] Recherche du bloc ID : {target_id}") movies_today = [] session = requests.Session() try: r = session.get(url_horaires, headers=HEADERS, timeout=15) soup = BeautifulSoup(r.content, 'html.parser') # 1. On cible le container du jour (ex: id="seance-2026-02-19") day_container = soup.find('div', id=target_id) if not day_container: logger.warning(f"[DEBUG] Bloc {target_id} non trouvé sur la page.") return [] # 2. On cherche tous les films du jour (balises li.heureReady) items = day_container.find_all('li', class_='heureReady') logger.info(f"[DEBUG] {len(items)} séances trouvées pour aujourd'hui.") for item in items: # Extraction du Titre et du Lien title_tag = item.select_one('.filmTitle a') if not title_tag: continue title = title_tag.get_text(strip=True) detail_path = title_tag.get('href') # Extraction de l'Heure (on nettoie "Début du film : 13h40") time_tag = item.select_one('.horaire_debut') time_raw = time_tag.get_text(strip=True) if time_tag else "" show_time = re.search(r'\d{2}h\d{2}', time_raw) show_time = show_time.group(0).replace('h', ':') if show_time else "Séance" # 3. Visite de la page de détails pour l'affiche img_url = "" if detail_path: detail_url = f"{BASE_URL}{detail_path}" logger.info(f"[DEBUG] -> Page détail : {title}") try: r_detail = session.get(detail_url, headers=HEADERS, timeout=10) soup_detail = BeautifulSoup(r_detail.content, 'html.parser') # Sélecteur d'après ta capture : img class="fc_field_image" img_tag = soup_detail.find('img', class_='fc_field_image') if img_tag: img_url = img_tag.get('src') if img_url and not img_url.startswith('http'): img_url = f"{BASE_URL}{img_url}" except Exception as e: logger.error(f"[DEBUG] Erreur page détail {title}: {e}") movies_today.append({ "title": title, "img": img_url, "times": [show_time], "cinema": "American Cosmograph" }) time.sleep(0.3) # Politesse except Exception as e: logger.error(f"[DEBUG] Erreur critique : {e}") # Fusion des horaires pour un même film (le Cosmo sépare les séances par bloc) unique_movies = {} for m in movies_today: if m['title'] not in unique_movies: unique_movies[m['title']] = m else: if m['times'][0] not in unique_movies[m['title']]['times']: unique_movies[m['title']]['times'].append(m['times'][0]) unique_movies[m['title']]['times'].sort() logger.info(f"[DEBUG] FIN : {len(unique_movies)} films uniques trouvés.") return list(unique_movies.values()) @app.route('/') def index(): films = scrape_cosmo_only() return render_template('index.html', films=films) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)