Google Finance est l'un des endroits les plus utilisés pour lire des données de marché en temps réel, et ses pages de cotation contiennent exactement les chiffres structurés qui alimentent le suivi des prix, la surveillance de portefeuille et la recherche : le prix en direct, la variation journalière en valeur et en pourcentage, la clôture précédente, et les métriques de marché clés comme la capitalisation boursière, le ratio P/E, et les plages journalières et annuelles de négociation. Pour quiconque surveille un panier de titres, ces données de marché publiques sont la matière première, et les copier manuellement sur des dizaines de symboles est lent et source d'erreurs.

Ce guide vous montre comment scraper Google Finance avec Python de manière fiable. Vous construirez un petit scraper fonctionnel qui récupère des pages de cotation rendues via la Crawling API, analyse les champs souhaités avec BeautifulSoup, boucle sur plusieurs titres et exporte du JSON propre. L'ensemble du tutoriel se limite aux données de marché publiques, qui sont factuelles plutôt que personnelles, et la section sur la légalité à la fin n'est pas un simple formulaire, alors lisez-la avant de l'utiliser à grande échelle.

Ce que vous allez construire

Un script Python qui prend une liste d'URLs de cotation Google Finance (une par titre, dans la forme SYMBOL:EXCHANGE utilisée par Google), récupère chaque page rendue via la Crawling API, et extrait un enregistrement structuré par action. L'exemple fil rouge utilise GOOGL, AAPL et MSFT sur NASDAQ. Nous extrayons ces champs :

  • Titre le nom de l'entreprise affiché en haut de la page de cotation.
  • Prix le prix coté actuel de l'action.
  • Variation la variation absolue de prix et son pourcentage pour la session.
  • Clôture précédente le prix de clôture de la session précédente.
  • Données de marché le bloc de métriques clés : capitalisation boursière, ratio P/E, et les plages journalières et annuelles quand elles sont présentes.

Pourquoi une simple requête échoue sur Google Finance

Demandez une URL de cotation Google Finance avec un client HTTP basique et vous obtenez une réponse avec le statut 200 mais seulement une fraction des données dans le corps. Deux facteurs jouent contre vous. D'abord, Google Finance remplit ses pages de cotation dans le navigateur avec JavaScript, donc le HTML initial est une coquille légère. Le signe le plus clair est le pourcentage de variation du prix : extrayez-le de cette première réponse et vous obtenez None, car cette valeur se rend côté client après le chargement. Ensuite, Google signale rapidement le trafic automatisé. Les IP de datacenter et les patterns de requêtes qui ne ressemblent pas à un vrai navigateur sont limités, bloqués par IP ou challengés avant d'atteindre le contenu rendu.

Un scraper Google Finance fonctionnel a donc besoin de deux choses en une seule requête : un navigateur qui rend réellement la page, et une IP que la plateforme considère comme un vrai visiteur. Vous pouvez construire cela vous-même avec un navigateur headless et un pool de proxies résidentiels rotatifs, mais maintenir ce stack en bonne santé représente l'essentiel du travail. La Crawling API regroupe les deux en un seul appel : envoyez-lui l'URL avec un token JavaScript, elle rend la page derrière une IP de confiance et renvoie le HTML finalisé à analyser. Pour le contexte plus large sur les cibles rendues, consultez comment crawler les sites web JavaScript.

Pourquoi le token JS

Crawlbase propose deux types de token. Le token normal récupère le HTML statique ; le token JavaScript (JS) rend d'abord la page dans un vrai navigateur. Google Finance remplit son prix, son pourcentage de variation et ses métriques côté client, donc vous avez besoin du token JS ici. Le token normal renvoie la même coquille légère qu'une simple requête, avec le pourcentage de variation manquant, et il y a peu d'utile à en extraire.

Prérequis

Vous avez besoin de quelques éléments en place avant d'écrire du code. Aucun ne prend longtemps.

Python de base. Vous devez être à l'aise pour écrire et exécuter un script Python et installer des paquets avec pip. Si vous débutez avec le côté analyse, le guide BeautifulSoup est un bon complément à ce tutoriel.

Python 3.8 ou version ultérieure. Confirmez votre version avec python --version. Si vous ne l'avez pas, installez-le depuis python.org ou via une distribution comme Anaconda, et assurez-vous que Python est dans votre PATH.

Un compte Crawlbase et un token JS. Inscrivez-vous, ouvrez votre tableau de bord, et copiez votre token JavaScript (JS) depuis la page de documentation du compte. Crawlbase inclut jusqu'à 20 000 requêtes gratuites pour commencer, largement suffisant pour travailler sur ce guide, et vous ne payez que pour les requêtes réussies. Traitez le token comme un mot de passe : il authentifie vos requêtes, donc ne le mettez pas dans le contrôle de version.

Configurer le projet

Créez un environnement virtuel pour garder les dépendances du projet isolées, puis installez les bibliothèques dont le scraper a besoin.

bash
python --version

python -m venv google_finance_env
source google_finance_env/bin/activate

pip install crawlbase beautifulsoup4

Sur Windows, activez l'environnement avec google_finance_env\Scripts\activate à la place de la ligne source. Deux dépendances font le travail : crawlbase est le client officiel pour la Crawling API, et beautifulsoup4 analyse le HTML renvoyé pour que vous puissiez extraire des champs individuels par sélecteur CSS. Le module json fait partie de la bibliothèque standard, donc il n'y a rien de plus à installer pour l'étape d'export.

Étape 1 : Récupérer une page Google Finance rendue

Commencez par obtenir une page finalisée. Importez la classe CrawlingAPI, initialisez-la avec votre token JS, et demandez une URL de cotation. Google Finance charge ses valeurs de manière asynchrone, donc passez ajax_wait et page_wait pour maintenir le contenu dynamique avant la capture de la page. Vérifier le cb_status (legacy pc_status) de Crawlbase avant d'analyser permet de détecter les échecs rapidement plutôt que silencieusement.

python
from crawlbase import CrawlingAPI

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"})

OPTIONS = {
    "ajax_wait": "true",
    "page_wait": 5000,
}

def crawl(page_url):
    response = api.get(page_url, OPTIONS)
    if response["headers"]["cb_status"] == "200":
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['headers']['cb_status']}")
    return None

if __name__ == "__main__":
    quote_url = "https://www.google.com/finance/quote/GOOGL:NASDAQ"
    html = crawl(quote_url)
    print(html[:500] if html else "No HTML returned")

Les deux options d'attente sont importantes pour une cible rendue côté client comme Google Finance. ajax_wait indique à l'API d'attendre que le contenu asynchrone ait fini de se charger, et page_wait maintient un nombre fixe de millisecondes après le chargement pour que les valeurs à rendu tardif apparaissent avant la capture de la page. Cinq secondes est un bon point de départ ; augmentez si le pourcentage de variation revient vide. Exécutez le script avec python google_finance_scraper.py et vous devriez voir le vrai balisage de la page de cotation, pas la coquille qu'une simple requête renvoie. Cela confirme que le rendu fonctionne avant d'écrire un seul sélecteur.

Crawlbase Crawling API

Google Finance nécessite une page rendue derrière une IP de confiance, en un seul appel, ce qui est exactement ce que les options ajax_wait et page_wait ci-dessus configurent. La Crawling API prend un token JS, exécute la page dans un vrai navigateur pour que le pourcentage de variation se charge réellement, effectue une rotation des IP résidentielles côté serveur, et vous remet le HTML finalisé, vous évitant de gérer vous-même une flotte headless et un pool de proxies. Pointez-la sur une page de cotation publique avec le niveau gratuit d'abord.

Étape 2 : Analyser le prix, la variation et le titre

Avec le HTML finalisé en main, chargez-le dans BeautifulSoup et extrayez les champs principaux. Google Finance conserve le nom de l'entreprise, le prix actuel et la variation de session dans la région main de la page, chacun dans une classe générée. Les sélecteurs ci-dessous proviennent directement de la mise en page de cotation en direct : le titre se trouve dans zzDege, le prix dans AHmHk, et le pourcentage de variation dans JwB6zf. Chaque recherche est protégée pour qu'un champ manquant renvoie None au lieu de faire planter l'exécution.

python
from bs4 import BeautifulSoup

def get_price(soup):
    el = soup.find("main")
    if not el:
        return None
    price = el.find("div", "AHmHk")
    return price.get_text(strip=True) if price else None

def get_change_percentage(soup):
    main = soup.find("main")
    if not main:
        return None
    change = main.find("div", "JwB6zf")
    return change.get_text(strip=True) if change else None

def get_stock_title(soup):
    main = soup.find("main")
    if not main:
        return None
    title = main.find("div", "zzDege")
    return title.get_text(strip=True) if title else None

L'élément JwB6zf est celui à surveiller. Sur une réponse légère non rendue, il est complètement absent et get_change_percentage renvoie None ; une fois la page rendue via le token JS, il porte la variation de session en valeur et en pourcentage. Ce seul champ est la preuve la plus simple que le rendu fait son travail.

Les sélecteurs dérivent

Les noms de classes générés par Google comme AHmHk, JwB6zf et zzDege changent sans préavis. Traitez les sélecteurs ici comme un modèle de départ, pas comme un contrat. Quand un champ revient à None sur une page clairement rendue, réinspectez la cotation en direct dans les outils de développement de votre navigateur et mettez à jour la classe. La maintenance périodique des sélecteurs est normale pour tout scraper en production, pas le signe que quelque chose est cassé.

Étape 3 : Analyser le bloc de données de marché

Sous les chiffres principaux, Google Finance liste les métriques clés sous forme de lignes label-valeur : clôture précédente, plage journalière, plage annuelle, capitalisation boursière, ratio P/E et plus encore. Chaque ligne est un conteneur gyFHrc contenant un label dans mfs7Fc et une valeur dans P6K39c. Transformer chaque ligne en dictionnaire rend le parseur résilient : quelles que soient les métriques exposées par un titre donné, elles apparaissent comme des clés, et vous lisez Previous close, Market cap, P/E ratio, Day range et Year range directement depuis ce dictionnaire.

python
def get_market_data(soup):
    rows = soup.find_all("div", {"class": "gyFHrc"})
    data = {}
    for row in rows:
        label = row.find("div", {"class": "mfs7Fc"})
        value = row.find("div", {"class": "P6K39c"})
        if label and value:
            data[label.get_text(strip=True)] = value.get_text(strip=True)
    return data

KEEP = ["Previous close", "Day range", "Year range", "Market cap", "P/E ratio"]

def select_market_fields(market_data):
    return {key: market_data[key] for key in KEEP if key in market_data}

L'helper get_market_data capture chaque paire label-valeur sur la page, vous n'avez donc pas à coder en dur un sélecteur par métrique. select_market_fields réduit ensuite cela à la portée définie ici : clôture précédente, plages journalières et annuelles, capitalisation boursière et ratio P/E. Comme le filtre vérifie if key in market_data, un titre qui omet l'un de ces éléments laisse simplement cette clé hors de l'enregistrement plutôt que d'échouer. Gardez la sortie complète de get_market_data si vous souhaitez plus tard obtenir aussi le volume moyen ou la bourse principale.

Étape 4 : Assembler le script complet

Maintenant, reliez les pièces en un seul script fonctionnel : récupérez chaque page de cotation, analysez les champs principaux et le bloc de marché, et exportez les enregistrements en JSON. La fonction extract_quote regroupe les helpers par champ en un seul enregistrement, et main boucle sur une liste d'URLs de cotation SYMBOL:EXCHANGE pour extraire plusieurs titres en une seule exécution.

python
import json
import time
from crawlbase import CrawlingAPI
from bs4 import BeautifulSoup

api = CrawlingAPI({"token": "YOUR_CRAWLBASE_TOKEN"})

OPTIONS = {
    "ajax_wait": "true",
    "page_wait": 5000,
}

KEEP = ["Previous close", "Day range", "Year range", "Market cap", "P/E ratio"]

def crawl(page_url):
    response = api.get(page_url, OPTIONS)
    if response["headers"]["cb_status"] == "200":
        return response["body"].decode("utf-8")
    print(f"Request failed: {response['headers']['cb_status']}")
    return None

def text_in_main(soup, class_name):
    main = soup.find("main")
    if not main:
        return None
    el = main.find("div", class_name)
    return el.get_text(strip=True) if el else None

def get_market_data(soup):
    rows = soup.find_all("div", {"class": "gyFHrc"})
    data = {}
    for row in rows:
        label = row.find("div", {"class": "mfs7Fc"})
        value = row.find("div", {"class": "P6K39c"})
        if label and value:
            data[label.get_text(strip=True)] = value.get_text(strip=True)
    return data

def extract_quote(html, url):
    soup = BeautifulSoup(html, "html.parser")
    market = get_market_data(soup)
    return {
        "url": url,
        "title": text_in_main(soup, "zzDege"),
        "price": text_in_main(soup, "AHmHk"),
        "change": text_in_main(soup, "JwB6zf"),
        "previous_close": market.get("Previous close"),
        "market_data": {key: market[key] for key in KEEP if key in market},
    }

def main():
    urls = [
        "https://www.google.com/finance/quote/GOOGL:NASDAQ",
        "https://www.google.com/finance/quote/AAPL:NASDAQ",
        "https://www.google.com/finance/quote/MSFT:NASDAQ",
    ]
    records = []
    for url in urls:
        html = crawl(url)
        if html:
            records.append(extract_quote(html, url))
        time.sleep(2)

    with open("finance_data.json", "w") as f:
        json.dump(records, f, indent=2)
    print(f"Saved {len(records)} quotes")

if __name__ == "__main__":
    main()

Le seul helper text_in_main remplace les trois fonctions presque identiques de titre, prix et variation des étapes précédentes : il trouve la région main, recherche une classe générée, et renvoie le texte nettoyé ou None. extract_quote assemble un enregistrement par titre, extrayant la clôture précédente du dictionnaire de marché et imbriquant le reste sous market_data. Le délai de deux secondes cadence l'exécution pour ne pas marteler le site. Modifiez la liste urls pour scraper d'autres symboles.

À quoi ressemble la sortie

Exécutez le script complet avec python google_finance_scraper.py et vous obtenez un enregistrement structuré propre par titre, prêt pour l'analyse, une base de données ou un tableur. Les valeurs ci-dessous sont illustratives ; votre exécution renvoie ce que la cotation en direct affiche.

json
[
  {
    "url": "https://www.google.com/finance/quote/GOOGL:NASDAQ",
    "title": "Alphabet Inc Class A",
    "price": "$163.79",
    "change": "+1.01 (0.62%)",
    "previous_close": "$162.78",
    "market_data": {
      "Previous close": "$162.78",
      "Day range": "$163.09 - $167.12",
      "Year range": "$103.71 - $174.71",
      "Market cap": "2.04T USD",
      "P/E ratio": "25.54"
    }
  },
  {
    "url": "https://www.google.com/finance/quote/AAPL:NASDAQ",
    "title": "Apple Inc",
    "price": "$169.30",
    "change": "-0.61 (0.36%)",
    "previous_close": "$170.33",
    "market_data": {
      "Previous close": "$170.33",
      "Day range": "$169.11 - $172.71",
      "Year range": "$164.08 - $199.62",
      "Market cap": "2.61T USD",
      "P/E ratio": "26.34"
    }
  }
]

Remarquez que le champ change porte maintenant une vraie valeur au lieu de null. Sur une simple requête non rendue, il revient vide car Google le peint côté client ; router la requête via le token JS est ce qui le fait apparaître. À partir de là, les enregistrements s'intègrent directement dans pandas ou tout tableur pour suivre les mouvements de prix, comparer les P/E à travers une liste de surveillance, ou alimenter un workflow de veille des prix.

Passer à grande échelle sur une liste de surveillance et rester non bloqué

Le script ci-dessus extrait trois titres, mais la forme s'adapte à une liste de surveillance complète en étendant la liste urls. À mesure que l'exécution grandit, quelques habitudes la maintiennent en bonne santé, et elles s'appliquent à toute cible difficile.

  • Cadencez vos requêtes. Marteler les cotations dans une boucle serrée est le moyen le plus rapide de se faire limiter ou challenger. Le délai de deux secondes ci-dessus est le plancher, pas le plafond ; élargissez-le pour les grandes listes de surveillance et variez vos symboles plutôt que de réextraire un seul chemin à pleine vitesse.
  • Misez sur la rotation. Un pool d'IP résidentielles répartit les requêtes sur de nombreuses adresses d'utilisateurs réels, de sorte qu'aucune ne déclenche une limite de débit. La Crawling API s'en charge pour vous ; si vous construisez votre propre stack, c'est la partie à bien faire.
  • Lisez les codes de statut. Une exécution qui commence à renvoyer des valeurs cb_status non-200 vous indique que le débit ou le niveau d'IP actuels ne sont plus suffisants. Traitez cela comme un signal pour ralentir, pas comme du bruit à ignorer.

Pour les grands travaux, le Crawler asynchrone met en file les requêtes et livre les résultats vers un webhook, ce qui convient à l'actualisation de nombreux titres selon un calendrier sans maintenir de connexions ouvertes. Pour le guide complet, consultez comment scraper des sites web sans se faire bloquer. La même approche rendu-plus-IP-de-confiance s'applique aussi à d'autres sources de marché, comme scraper les prix crypto depuis CoinMarketCap.

Est-il légal de scraper Google Finance ?

La question de savoir si le scraping de Google Finance est autorisé dépend des conditions d'utilisation de Google, de votre juridiction et de ce que vous faites avec les données. Les conditions de Google restreignent l'accès automatisé à ses services, donc le scraping peut aller à l'encontre de ces conditions quelle que soit la prudence de vos outils. Aucun code ici ne change cela ; il fait seulement fonctionner la partie technique. Lisez les Conditions d'utilisation de Google et le robots.txt pour les chemins Google Finance, et traitez les deux comme la limite de ce que vous collectez et à quelle fréquence vous le demandez.

Les données que ce guide cible sont fermement du côté public et non personnel : les prix des actions, la variation de session, la clôture précédente, la capitalisation boursière, le ratio P/E et les plages journalières et annuelles sont des chiffres de marché factuels, pas des informations personnelles de qui que ce soit. Cela rend le travail plus étroit que le scraping de sites portant du contenu utilisateur, mais cela ne vous place pas au-dessus des conditions de Google. Restez sur les pages de cotation que tout visiteur peut charger sans compte, maintenez votre volume de requêtes suffisamment bas pour ne pas surcharger les serveurs de Google, et ne redistribuez pas les flux de marché sous-jacents en gros, car les bourses et les fournisseurs de données licencient ces chiffres et cette licence suit les chiffres.

Ce guide est délibérément limité aux pages de cotation publiques car c'est la ligne qui rend le travail défendable. Il ne couvre pas ce qui se trouve derrière une connexion, les données payantes ou premium, ni aucune tentative de contournement de l'authentification ou des limites de débit. Si votre projet nécessite une disponibilité garantie, des droits de redistribution ou un volume supérieur à ce que permet un scraping poli, la bonne voie est un flux sous licence : utilisez une API de données de marché officielle ou un flux de bourse sous licence pour la production. C'est la route appropriée pour un usage commercial ou en masse, pas un scraper plus agressif.

Récapitulatif

Points clés

  • Google Finance est rendu côté client. Une simple requête renvoie une coquille légère avec le pourcentage de variation du prix manquant, vous devez donc rendre la page avant de l'analyser.
  • Vous avez besoin du rendu et d'une IP de confiance ensemble. La Crawling API avec un token JS fait les deux en un seul appel ; ajax_wait et page_wait contrôlent le temps d'attente du chargement des valeurs.
  • Mappez les champs aux vraies classes. Le titre se trouve dans zzDege, le prix dans AHmHk, et la variation de session dans JwB6zf ; le bloc de métriques est un ensemble de lignes gyFHrc associant un label mfs7Fc à une valeur P6K39c.
  • Bouclez et exportez. Passez une liste d'URLs de cotation SYMBOL:EXCHANGE, cadencez l'exécution avec de courts délais, et écrivez un enregistrement par titre en JSON avec les données de marché imbriquées.
  • Restez sur les données de marché publiques. Respectez les CGU et robots.txt de Google, limitez-vous aux cotations publiques factuelles, et utilisez une API de données de marché officielle ou un flux sous licence pour la production ou la redistribution.

Foire aux questions

Pourquoi le pourcentage de variation du prix est-il null sur une simple requête ?

Parce que Google Finance rend cette valeur côté client avec JavaScript. Le HTML initial est une coquille, et l'élément JwB6zf qui contient la variation de session n'apparaît qu'après l'exécution des scripts de la page dans un navigateur. Une requête HTTP brute renvoie le statut 200 avec la variation manquante, ce qui explique pourquoi le champ revient à None. Rendre d'abord la page, ce que gère le token JS de la Crawling API, rend la valeur présente pour que BeautifulSoup puisse la lire.

Dois-je utiliser le token normal ou le token JS pour Google Finance ?

Le token JS. Le token normal récupère le HTML statique, qui sur Google Finance est la même coquille légère qu'une simple requête renvoie, avec le pourcentage de variation absent. Le token JS rend la page dans un vrai navigateur avant de restituer le HTML, donc le prix, la variation et le bloc de métriques sont tous présents quand vous les analysez.

Quelles données puis-je scraper d'une page de cotation Google Finance ?

Les champs de marché publics : le titre de l'entreprise, le prix actuel, la variation de session en valeur et en pourcentage, la clôture précédente, et le bloc de métriques qui inclut la capitalisation boursière, le ratio P/E, et les plages journalières et annuelles quand elles sont présentes. Ce sont des cotations publiques factuelles que tout visiteur peut charger, pas des données personnelles. Restez dans cette portée et utilisez un flux sous licence si vous avez besoin de droits de redistribution.

Mes sélecteurs retournent None. Qu'est-ce qui a changé ?

Presque certainement le balisage de Google. Ses noms de classes générés (AHmHk pour le prix, JwB6zf pour la variation, zzDege pour le titre, et gyFHrc / mfs7Fc / P6K39c pour les lignes de métriques) changent sans préavis, donc les sélecteurs qui fonctionnaient le mois dernier peuvent casser. Réinspectez une cotation en direct dans les outils de développement de votre navigateur et mettez à jour les chaînes de classes. La maintenance périodique des sélecteurs est normale pour tout scraper en production.

Comment scraper plusieurs actions à la fois ?

Google Finance adresse chaque action comme SYMBOL:EXCHANGE dans l'URL de cotation, par exemple GOOGL:NASDAQ. Construisez une liste de ces URLs et bouclez dessus, en appelant la même fonction extract_quote sur chaque page rendue, comme le montre la fonction main ci-dessus. Maintenez un court délai entre les requêtes pour cadencer l'exécution, et étendez la liste pour couvrir votre liste de surveillance complète.

Existe-t-il une API officielle Google Finance pour la production ?

Google ne propose pas d'API de données de marché publique et supportée pour Google Finance, donc pour un usage en production ou commercial, la voie fiable est un fournisseur de données de marché sous licence ou un flux de bourse officiel plutôt que de scraper la page web. Ces flux sont accompagnés de garanties de disponibilité et de conditions de redistribution que le scraping d'une page publique n'offre pas, ce qui compte dès que la précision des données ou les droits de réutilisation font partie des exigences.

Commencer à construire

Crawlez n'importe quel site à grande échelle, sans combattre l'infrastructure.

Crawlbase gère les proxies, les empreintes et les CAPTCHA afin que votre équipe livre des pipelines de données au lieu de maintenir la plomberie de crawl. 1 000 requêtes gratuites, sans carte requise.

En libre-service · Sans appel commercial requis · Volumes de crawl entreprise disponibles