Skip to content

Repository files navigation

IC05 - Analyse de données Letterboxd

Pipeline de collecte, nettoyage et analyse de données de films scrappées sur Letterboxd, réalisé dans le cadre de l'UV IC05 - Technologies pour la documentation et l'indexation dans l'hypermédia. L'objectif du projet est de répondre à la question suivante : qu'est-ce qui rend un film populaire sur Letterboxd ? un casting connu ? le pays de production ? le genre ? et peut-on le mesurer plutôt que l'affirmer ?

Pour ceci le projet utilise une DB PostgreSQL, la librairie Selenium pour naviguer à travers les pages de Letterboxd, et Pyhton pour l'extraction, nettoyage et analyse des données.

Architecture

docker-compose.yml   PostgreSQL 16 + Adminer
db/schema.sql        Schéma normalisé et vues SQL
db/seed/             Échantillon de données (chargé automatiquement au premier démarrage)
src/ic05/
  collecte/          Scraping Letterboxd -> JSON brut (data/raw/films/)
  nettoyage/         JSON brut -> PostgreSQL (idempotent, upserts)
  analyse/           PostgreSQL -> statistiques, figures, graphes réseau (output/)
scripts/             CLI alternative + migration de l'échantillon legacy
notebooks/           Notebook de démonstration
tests/               Tests unitaires (nettoyage + parsing du scraper)

Pourquoi (presque) pas de Selenium

Contrairement aux conseils de Mme BELLON Anne, nous n'avons que très peu utilisé la librairie Selenium , pour les raisons suivantes :

  • le bloc <script type="application/ld+json"> de chaque page contient déjà le titre, l'année, le réalisateur, les genres, le(s) pays d'origine, le casting complet et la note agrégée ;
  • les vues et les likes sont exposés par un endpoint statique (/csi/film/<slug>/stats/) avec le nombre exact dans l'attribut aria-label ;
  • seuls les thèmes (/film/<slug>/genres/) demandent une requête HTTP de plus.

Résultat : le détail d'un film se scrape avec 3 requêtes requests simples, sans navigateur (voir src/ic05/collecte/films.py), ce qui s'avère bien plus rapide que de faire tourner Selenium sur un/des navigateur(s).

Selenium ne sert ici qu'à parcourir le catalogue par décennie (/films/decade/...), dont la grille de posters est peuplée en React côté client.

Démarrage rapide

Prérequis : Docker, Python 3.11+.

cp .env.example .env
make up           # démarre Postgres (+ échantillon de données seedé) et Adminer
make install      # crée le venv et installe le package ic05
make analyser     # lance toutes les analyses -> output/figures, output/network, output/resultats.json

Adminer est accessible sur http://localhost:8080 (serveur db, utilisateur/mot de passe/base : voir .env).

Pour relancer le pipeline de collecte depuis zéro (nécessite Chrome/Chromium installé localement pour collecte-liens, voir Limites) :

make scrape-liens DECENNIE=2010s   # remplit liens_films
make scrape-films                  # scrape le détail -> data/raw/films/*.json
make nettoyer                      # charge data/raw/films/ dans PostgreSQL

Analyses

Chaque module de src/ic05/analyse/ formule une analyse sur les données récupérées :

Module Intérêt
stats_temporel.py Vérifie l'hypothèse (doublons de titre/année) plutôt que de la laisser ouverte ; ajoute l'évolution de l'engagement (nb de votants)
stats_notoriete.py Acteurs "notables" détectés génériquement (percentile de vues), test de Mann-Whitney (avec/sans acteur notable) et régression OLS log(vues) ~ acteur + pays + genre + année pour isoler l'effet acteur du reste
stats_pays.py ANOVA (le pays a-t-il un effet significatif sur la note ? avec quelle taille d'effet η²) + carte choroplèthe interactive
stats_genres.py Heatmap genre × pays généralisée à tous les pays significatifs, test du χ² d'indépendance genre/pays, évolution des proportions de genres dans le temps
reseau.py Graphe acteur-acteur (networkx) avec centralités et détection de communautés (Louvain), graphe réalisateur-acteur pour détecter les duos récurrents, graphe de co-occurrence des genres - rendu interactif exporté en HTML (pyvis)

make analyser (ou ic05 analyser) exécute les cinq modules et écrit :

  • des figures statiques dans output/figures/*.png ;
  • des figures interactives (carte, heatmap) dans output/figures/*.html ;
  • des graphes réseau interactifs dans output/network/*.html ;
  • l'ensemble des résultats chiffrés (tests statistiques, régressions, tops) dans output/resultats.json.

Le notebook notebooks/exploration.ipynb montre comment appeler ces modules directement pour explorer les résultats de façon interactive.

Limites connues

  • Catalogue et Selenium : parcourir le catalogue par décennie (collecte-liens) nécessite un Chrome/Chromium installé localement (Selenium pilote un navigateur headless, la grille de posters étant peuplée côté client). Le scraping du détail d'un film (collecte-films), en revanche, ne dépend plus de Selenium et peut donc tourner plus facilement (voir tests/test_collecte_films.py).
  • Volumétrie : Letterboxd semble être derrière Cloudflare ; un run de collecte massif (des dizaines de milliers de films) reste lent et doit respecter un délai entre requêtes (IC05_SCRAPE_DELAY dans .env), sans garantie de ne jamais être bloqué.
  • Pays déduit de la langue : quand une fiche film n'indique pas de pays de production, on retombe sur la langue principale (est_langue = TRUE dans film_pays) - approximation déjà présente dans le projet original.

About

Projet de Scrpping et Analyse de Letterboxd pour l'UV IC05 - Analyse critique des données numériques

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages