Comment scraper Reddit avec des proxies : guide complet pour données publiques

Apprenez à scraper les données publiques de Reddit avec des proxies résidentiels : contournement des limites de l'API, extraction via old.reddit.com, gestion des rate limits et bonnes pratiques éthiques.

Comment scraper Reddit avec des proxies : guide complet pour données publiques

Pourquoi scraper Reddit en 2025 ? Le contexte API en pleine mutation

Si vous lisez cet article, vous avez probablement déjà ressenti la frustration : les données Reddit sont incroyablement riches pour la recherche de marché, l'analyse de sentiment ou le suivi de tendances, mais y accéder est devenu un parcours du combattant. Avant 2023, l'API officielle de Reddit était généreuse — gratuite, largement ouverte, et suffisamment bien documentée pour que n'importe quel développeur puisse récupérer des posts et commentaires sans friction.

Tout a changé en juillet 2023. Reddit a introduit une tarification API qui a fait l'effet d'une bombe dans la communauté : 0,24 $ pour 100 requêtes API, soit des milliers de dollars par mois pour des volumes modestes de collecte de données. Des applications tierces populaires comme Apollo, Rif et Sync ont dû fermer. Des projets de recherche académique ont été paralysés. Et des équipes data comme la vôtre se sont retrouvées face à un choix brutal : payer des sommes considérables, ou trouver une autre voie.

Attention : Ce guide se concentre exclusivement sur l'accès à des données publiques sur Reddit. Le scraping de données privées, le contournement de mesures de sécurité, ou la violation des Conditions d'Utilisation de Reddit peuvent constituer des infractions au CFAA (US), au RGPD (UE), ou à d'autres lois applicables. Utilisez ces techniques de manière responsable et légale.

C'est dans ce contexte que le scraping Reddit — via les pages web plutôt que l'API — est redevenu une stratégie pertinente, en particulier pour les projets sensibles aux coûts. Mais Reddit ne facilite pas la tâche : rate limits agressives, pattern de blocage 429→403, fingerprinting de navigateur. C'est là que les proxies entrent en jeu.

Quelles données publiques sont accessibles sur Reddit ?

Reddit expose une quantité considérable de données publiques, accessibles sans authentification. Voici les principales catégories et les endpoints correspondants :

Flux de subreddits

Chaque subreddit propose des pages de listing publiques : https://old.reddit.com/r/subreddit/ pour les posts « hot », /new/ pour les plus récents, /top/?t=day pour les meilleurs sur une période. Ces pages listent 25 posts par page avec pagination.

Pages de posts et fils de commentaires

Un post individuel et ses commentaires sont accessibles via https://old.reddit.com/r/subreddit/comments/post_id/. Les commentaires sont chargés dans le HTML initial — pas de lazy-loading comme sur le nouveau site. C'est un avantage majeur pour le scraping.

Pages utilisateur

Les profils publics (posts, commentaires) sont accessibles via https://old.reddit.com/user/username/. Notez que Reddit permet aux utilisateurs de masquer leur profil, auquel cas ces pages renvoient un 403 ou 404.

Recherche

La recherche Reddit est accessible via https://old.reddit.com/search?q=query&sort=new. Les résultats sont paginés et incluent des posts et des commentaires publics.

old.reddit.com : l'alternative scraping-friendly

C'est le secret le mieux gardé des scrapers Reddit. old.reddit.com est la version héritée du site, conservée pour les utilisateurs réfractaires au redesign. Pourquoi est-ce préférable pour le scraping ?

  • HTML statique : le contenu est dans la réponse initiale, pas chargé dynamiquement via JavaScript
  • Structure HTML simple et prévisible : facile à parser avec BeautifulSoup
  • Moins de fingerprinting : moins de JavaScript de tracking côté client
  • Pas de lazy-loading : les commentaires sont entièrement dans le HTML

En revanche, old.reddit.com partage les mêmes rate limits que le site principal.

Choisir le bon type de proxy pour Reddit

Tous les proxies ne se valent pas face à Reddit. Le choix dépend de votre volume, de votre fréquence, et de vos besoins en géolocalisation.

CritèreDatacenterRésidentielMobile
VitesseRapide (10-50ms)Moyenne (100-300ms)Lente (300-800ms)
Détection par RedditÉlevée — plages IP connuesFaible — IPs d'ISP réels
CoûtBas (~1-2 $/GB)Moyen (~5-15 $/GB)Élevé (~15-30 $/GB)
Volume recommandé< 1 000 requêtes/heure1 000-50 000 req/heureCas spécifiques uniquement
Géo-ciblageLimitéPays + villePays + opérateur
Risque de blocageÉlevé sur RedditFaibleTrès faible

Pour le Reddit data scraping sérieux — analyse de sentiment sur des dizaines de subreddits, suivi de tendances en temps réel, collecte de données pour l'entraînement d'IA — les proxies résidentiels sont la solution la plus fiable. Reddit est agressif sur le blocage des IPs datacenter, et un pool résidentiel vous permet de répartir vos requêtes sur des milliers d'IPs d'ISP réelles.

Pour des volumes faibles (monitoring ponctuel d'un subreddit), un proxy datacenter peut suffire, mais attendez-vous à des blocages fréquents.

Scraping Reddit en Python avec proxies résidentiels

Passons à la pratique. Voici un exemple complet utilisant requests, BeautifulSoup, et le pool de proxies résidentiels ProxyHat avec rotation automatique.

Configuration de base

import requests
from bs4 import BeautifulSoup
import time
import json

# Configuration ProxyHat — rotation par requête
PROXY_URL = "http://user-country-US:PASSWORD@gate.proxyhat.com:8080"

HEADERS = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                  "AppleWebKit/537.36 (KHTML, like Gecko) "
                  "Chrome/125.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
}

session = requests.Session()
session.proxies = {"http": PROXY_URL, "https": PROXY_URL}
session.headers.update(HEADERS)

def fetch_subreddit(subreddit, sort="hot", limit=100):
    """Scrape les posts d'un subreddit via old.reddit.com."""
    posts = []
    after = None
    
    while len(posts) < limit:
        url = f"https://old.reddit.com/r/{subreddit}/{sort}/"
        if after:
            url += f"?after={after}"
        
        try:
            resp = session.get(url, timeout=15)
            
            if resp.status_code == 429:
                print("Rate limited — pause 60s")
                time.sleep(60)
                continue
            elif resp.status_code == 403:
                print("Bloqué (403) — rotation IP nécessaire")
                break
            
            resp.raise_for_status()
        except requests.RequestException as e:
            print(f"Erreur: {e}")
            time.sleep(10)
            continue
        
        soup = BeautifulSoup(resp.text, "html.parser")
        
        for thing in soup.select("div.thing[data-fullname]"):
            title_el = thing.select_one("a.title")
            score_el = thing.select_one("div.score.unvoted")
            author_el = thing.select_one("a.author")
            time_el = thing.select_one("time")
            
            if not title_el:
                continue
            
            posts.append({
                "id": thing["data-fullname"],
                "title": title_el.get_text(strip=True),
                "url": title_el.get("href", ""),
                "score": score_el.get_text(strip=True) if score_el else "0",
                "author": author_el.get_text(strip=True) if author_el else "[deleted]",
                "subreddit": subreddit,
                "timestamp": time_el["datetime"] if time_el else None,
            })
            
            after = thing["data-fullname"]
        
        # Respecter les rate limits — 2 requêtes/seconde max
        time.sleep(0.5)
    
    return posts[:limit]

# Utilisation
data = fetch_subreddit("datascience", sort="hot", limit=50)
print(json.dumps(data[:3], indent=2))

Scraping des commentaires avec sessions persistantes

Pour les fils de commentaires, vous voudrez utiliser une session sticky (IP fixe pour la durée de la session) afin d'éviter les incohérences :

def fetch_comments(subreddit, post_id, post_slug=""):
    """Scrape les commentaires d'un post."""
    # Session sticky — même IP pendant 10 minutes
    sticky_proxy = "http://user-session-reddit123-country-US:PASSWORD@gate.proxyhat.com:8080"
    
    sess = requests.Session()
    sess.proxies = {"http": sticky_proxy, "https": sticky_proxy}
    sess.headers.update(HEADERS)
    
    url = f"https://old.reddit.com/r/{subreddit}/comments/{post_id}/{post_slug}/"
    resp = sess.get(url, timeout=20)
    resp.raise_for_status()
    
    soup = BeautifulSoup(resp.text, "html.parser")
    comments = []
    
    for comment in soup.select("div.comment"):
        author_el = comment.select_one("a.author")
        score_el = comment.select_one("span.score.unvoted")
        text_el = comment.select_one("div.md")
        time_el = comment.select_one("time")
        
        comments.append({
            "author": author_el.get_text(strip=True) if author_el else "[deleted]",
            "score": score_el.get_text(strip=True) if score_el else "0",
            "text": text_el.get_text(strip=True) if text_el else "",
            "timestamp": time_el["datetime"] if time_el else None,
        })
    
    return comments

# Utilisation
comments = fetch_comments("datascience", "1d4k7h", "weekly_entering_thread")
print(f"Commentaires collectés : {len(comments)}")

Version Node.js avec axios et cheerio

const axios = require('axios');
const cheerio = require('cheerio');

const PROXY_URL = 'http://user-country-US:PASSWORD@gate.proxyhat.com:8080';

const HEADERS = {
  'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
    + 'AppleWebKit/537.36 (KHTML, like Gecko) '
    + 'Chrome/125.0.0.0 Safari/537.36',
  'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
};

async function scrapeSubreddit(subreddit, maxPosts = 50) {
  const posts = [];
  let after = null;
  
  while (posts.length < maxPosts) {
    let url = `https://old.reddit.com/r/${subreddit}/hot/`;
    if (after) url += `?after=${after}`;
    
    try {
      const resp = await axios.get(url, {
        proxy: { host: 'gate.proxyhat.com', port: 8080, auth: { username: 'user-country-US', password: 'PASSWORD' } },
        headers: HEADERS,
        timeout: 15000,
      });
      
      if (resp.status === 429) {
        console.log('Rate limited — pause 60s');
        await new Promise(r => setTimeout(r, 60000));
        continue;
      }
      
      const $ = cheerio.load(resp.data);
      
      $('div.thing[data-fullname]').each((_, el) => {
        const $el = $(el);
        posts.push({
          id: $el.attr('data-fullname'),
          title: $el.find('a.title').text().trim(),
          score: $el.find('div.score.unvoted').text().trim() || '0',
          author: $el.find('a.author').text().trim() || '[deleted]',
        });
        after = $el.attr('data-fullname');
      });
      
      await new Promise(r => setTimeout(r, 500));
    } catch (err) {
      console.error('Erreur:', err.message);
      await new Promise(r => setTimeout(r, 10000));
    }
  }
  
  return posts.slice(0, maxPosts);
}

scrapeSubreddit('machinelearning', 25).then(posts => {
  console.log(`Collecté ${posts.length} posts`);
});

Comprendre et gérer les rate limits de Reddit

Reddit applique des rate limits agressives, et le pattern d'escalade est particulier. Voici ce que vous devez savoir :

Le pattern 429 → 403

Reddit ne se contente pas de renvoyer des 429 indéfiniment. Le pattern typique est le suivant :

  1. Requêtes normales (200) — tout fonctionne
  2. Premiers avertissements (429) — « ralentissez », avec un header Retry-After
  3. Escalade (403) — votre IP est temporairement bloquée, parfois pour des heures
  4. Blocage prolongé — si vous continuez à insister, le blocage s'allonge

Ce pattern rend la rotation d'IP critique. Avec un proxy résidentiel rotatif, chaque requête utilise une IP différente, ce qui empêche l'accumulation de rate limits sur une seule adresse.

Limites par IP et par User-Agent

Reddit applique des limites simultanément sur l'IP et le User-Agent :

  • Par IP : environ 60 requêtes/minute pour les utilisateurs non authentifiés sur old.reddit.com
  • Par User-Agent : un User-Agent inhabituel ou générique (ex: python-requests/2.28) déclenche des limites plus strictes
  • Combiné : si Reddit détecte un pattern de scraping (même UA, IPs variées, volume élevé), il peut appliquer un shadow-ban au niveau du sous-réseau

Stratégie de backoff avec rotation

import requests
import time
import random

PROXY_URL = "http://user-country-US:PASSWORD@gate.proxyhat.com:8080"

def resilient_get(url, max_retries=5):
    """GET avec backoff exponentiel et rotation d'IP."""
    session = requests.Session()
    session.proxies = {"http": PROXY_URL, "https": PROXY_URL}
    session.headers.update({
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                      "AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/125.0.0.0 Safari/537.36",
    })
    
    for attempt in range(max_retries):
        try:
            resp = session.get(url, timeout=15)
            
            if resp.status_code == 200:
                return resp
            
            elif resp.status_code == 429:
                retry_after = int(resp.headers.get("Retry-After", 60))
                wait = min(retry_after * (2 ** attempt) + random.uniform(0, 5), 300)
                print(f"429 reçu — attente {wait:.0f}s (tentative {attempt+1})")
                time.sleep(wait)
                
            elif resp.status_code == 403:
                # IP bloquée — la rotation ProxyHat résout cela
                wait = 30 * (2 ** attempt) + random.uniform(0, 10)
                print(f"403 reçu — pause {wait:.0f}s (tentative {attempt+1})")
                time.sleep(wait)
                
            else:
                resp.raise_for_status()
                
        except requests.RequestException as e:
            print(f"Erreur réseau: {e}")
            time.sleep(10 * (2 ** attempt))
    
    return None

Meilleures pratiques pour un scraping Reddit fiable

1. Configurez un User-Agent réaliste

Ne laissez jamais le User-Agent par défaut de votre bibliothèque HTTP. Utilisez un UA de navigateur courant et variez-le légèrement entre vos sessions :

import random

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4 Safari/605.1.15",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:126.0) Gecko/20100101 Firefox/126.0",
]

def random_ua():
    return random.choice(USER_AGENTS)

2. Respectez les rate limits

Même avec des proxies rotatifs, imposez-vous une limite conservatrice :

  • 1-2 requêtes/seconde par IP (soit 60-120/minute)
  • Pause de 1 seconde minimum entre les pages de pagination
  • Backoff immédiat sur tout 429 ou 4xx inattendu

3. Cachez agressivement

Les données Reddit ne changent pas toutes les secondes. Un post vieux de 3 heures sera identique dans 5 minutes. Implémentez un cache local :

  • Cache disque avec requests-cache pour les posts anciens
  • TTL différencié : 5 min pour les listings « hot », 1 heure pour les posts de plus de 24h, 24 heures pour les posts de plus d'une semaine
  • Déduplication : stockez les IDs déjà collectés dans un set pour éviter les doublons

4. Utilisez old.reddit.com systématiquement

Le nouveau site Reddit (www.reddit.com) charge le contenu via JavaScript, ce qui nécessite un navigateur headless (Playwright, Puppeteer) — plus lent, plus complexe, et plus facile à détecter. old.reddit.com vous donne tout le contenu en HTML statique.

5. Répartissez la charge temporelle

Pour des collectes massives, étalez vos requêtes sur la journée plutôt que de tout lancer en rafale. Un schedule de collecte réparti réduit le risque de détection et de blocage.

6. Gérez les données login-walled vs publiques

Tout ce qui est visible sans connexion sur Reddit est techniquement public. Cela inclut :

  • Posts et commentaires sur les subreddits publics
  • Profils utilisateurs publics
  • Résultats de recherche sur des contenus publics

Ce qui n'est pas accessible légitimement sans authentification :

  • Messages privés
  • Subreddits privés ou restreints
  • Contenu supprimé (sauf archives tierces)
  • Données de vote individuelles (upvote/downvote par utilisateur)

Ne tentez jamais de scraper des données nécessitant une authentification — c'est une violation claire des conditions de Reddit et potentiellement des lois applicables.

Données avec vs sans authentification

Type de donnéesAccès publicNécessite un login
Posts de subreddits publics✅ Oui
Commentaires publics✅ Oui
Profils utilisateurs publics✅ Oui
Recherche publique✅ Oui
Subreddits privés✅ Oui
Messages privés✅ Oui
Historique de vote✅ Oui
Contenu NSFW (via old.reddit)⚠️ Partiel✅ Pour l'accès complet

Cas d'usage concrets

Analyse de sentiment sur des marques

Scrapez les posts et commentaires mentionnant une marque sur des subreddits pertinents, puis passez le texte dans un modèle NLP pour mesurer le sentiment. Les proxies résidentiels Reddit sont essentiels ici car vous devez couvrir de nombreux subreddits simultanément.

Suivi de tendances et mèmes

Surveillez les subreddits comme r/memes, r/dankmemes, r/whenthe pour détecter les formats émergents. Le volume est élevé — la rotation d'IP est indispensable.

Recherche académique

L'API Reddit coûte trop cher pour la plupart des budgets de recherche. Le scraping via old.reddit.com avec des proxies résidentiels offre une alternative viable pour les études à grande échelle sur le discours en ligne.

Surveillance de marché

Les subreddits comme r/investing, r/stocks, r/cryptocurrency contiennent des signaux précieux. Un scraping régulier avec des proxies résidentiels permet de capter ces signaux en temps réel.

Scraping éthique : quand utiliser l'API officielle plutôt que le scraping

Le scraping n'est pas toujours la bonne solution. Avant de scraper, posez-vous ces questions :

  1. Les données sont-elles disponibles via l'API officielle à un coût raisonnable ? Si vous avez besoin de moins de 100 requêtes/minute et que votre budget le permet, l'API officielle est plus fiable et légale.
  2. Respectez-vous robots.txt ? Reddit autorise le crawling limité, mais pas à des volumes massifs. Vérifiez https://www.reddit.com/robots.txt régulièrement.
  3. Les données sont-elles vraiment publiques ? Ne scrapez jamais de contenu qui nécessite un compte pour être consulté.
  4. Allez-vous republier ces données ? La redistribution de données Reddit peut violer les conditions d'utilisation et le droit d'auteur.
  5. Avez-vous un besoin légitime ? La recherche académique, l'analyse de marché interne et le monitoring de marque sont généralement acceptables. Le harcèlement, le doxxing ou la manipulation ne le sont jamais.

Reddit propose également des datasets publics via r/datasets et des partenariats de recherche. Vérifiez si vos données sont déjà disponibles avant de scraper.

Rappel RGPD/CCPA : Si vous collectez des données personnelles (noms d'utilisateur, contenu posté par des individus identifiables), vous avez des obligations légales en matière de protection des données, notamment le droit à l'effacement et la minimisation des données. Anonymisez systématiquement les données lorsque c'est possible.

Points clés à retenir

  • L'API Reddit est devenue coûteuse — le scraping via old.reddit.com est une alternative viable pour les données publiques, à condition de respecter les limites techniques et légales.
  • old.reddit.com est votre meilleur ami — HTML statique, pas de JavaScript, structure prévisible, commentaires entièrement chargés.
  • Les proxies résidentiels sont quasi-obligatoires pour tout volume supérieur à quelques centaines de requêtes. Reddit bloque rapidement les IPs datacenter.
  • Le pattern 429→403 exige une stratégie de rotation d'IP et de backoff exponentiel.
  • Cachez agressivement — les données Reddit ne changent pas toutes les secondes, et le cache réduit votre volume de requêtes de 70-90%.
  • Ne scrapez que des données publiques — ne contournez jamais les murs d'authentification, et respectez le RGPD et les conditions de Reddit.
  • Quand l'API officielle suffit, utilisez-la — le scraping est un outil, pas une religion.

Prêt à collecter des données Reddit ?

ProxyHat offre un pool de proxies résidentiels avec rotation automatique, couverture géographique dans 190+ pays, et une fiabilité éprouvée pour le scraping de plateformes web exigeantes comme Reddit. Consultez nos offres ou explorez nos localisations pour commencer.

Pour aller plus loin sur les techniques de scraping web, consultez notre guide complet de web scraping et notre article sur le suivi SERP avec proxies.

Prêt à commencer ?

Accédez à plus de 50M d'IPs résidentielles dans plus de 148 pays avec filtrage IA.

Voir les tarifsProxies résidentiels
← Retour au Blog