Scrap (Google Maps)
Module source qui extrait des fiches Google Maps pour un ensemble de requêtes sur une ou plusieurs zones géographiques, dans l'un des ~199 pays.
Purpose
Module source : exécute chaque requête sur chaque point de grille couvrant les zones demandées et retourne un CSV à plat d'établissements Google Maps (nom, contact, localisation, note).
Inputs
| Field | Type | Required | Description |
|---|---|---|---|
queries |
string[] (1–20) |
yes | Termes recherchés sur Google Maps. Chaque requête est trimée et plafonnée à 200 caractères. |
country |
string (ISO3) |
no | Pays ciblé, code ISO-3166 alpha-3 (ex. FRA, USA, DEU). Défaut "FRA". Détermine à la fois la grille GPS et la façon dont les zones sont résolues. |
zones |
string[] (1–50) |
yes | Zones géographiques exprimées dans country : un état/une région (adm1), un comté/département (adm2), une ville avec rayon optionnel ("Austin 30km"), ou le nom du pays pour scraper le pays entier. Pour la France, les codes INSEE, codes département et codes postaux restent valides. Chaque zone est résolue en grille de points côté serveur. Les noms de villes et de régions sont acceptés dans les langues usuelles ("Bruxelles", "Brussel" et "Brussels" désignent le même lieu), et les communes associées ou déléguées françaises ("Lomme") se résolvent à leur propre emplacement. Un nom porté par plusieurs villes désigne la plus peuplée ; un nom porté à la fois par une grande ville et par la zone qui l'entoure désigne la ville ("Anvers", "New York"), et la zone entière se demande par son titre ("Province d'Anvers", "New York State"). La Corse s'écrit "2A", "2B" ou "Corse". Les départements d'outre-mer (Guadeloupe, Martinique, Guyane, La Réunion, Mayotte) se demandent par leur nom ou leur code ("Martinique", "974"), ou par une de leurs communes ou un code postal ; "France" seule ne les inclut pas. Une commune d'outre-mer qui porte le même nom qu'une commune de métropole s'écrit avec son département ("Saint-Denis 974", "Saint-Denis La Réunion") ou son code postal ("97400"). |
include_reviews |
bool |
no | Conservé pour compatibilité ascendante. Ne chaîne pas un job reviews : utiliser le module reviews à la place. Défaut false. |
max_per_phone |
int (0–10) |
no | Fiches maximum gardées par numéro de téléphone. 0 (défaut) = aucune limite ; 1 = un seul contact par numéro. Les fiches sans numéro ne sont jamais écartées. Une même fiche n'apparaît jamais deux fois, quoi qu'il arrive. Voir Doublons. |
exclude_foreign_phones |
bool |
no | true (défaut) : écarte les fiches dont le numéro porte l'indicatif d'un autre pays. Les numéros sans indicatif et les fiches sans numéro sont gardés. Voir Numéros étrangers. |
Corps de requête :
{
"queries": ["plombier", "chauffagiste"],
"country": "FRA",
"zones": ["75", "92"],
"include_reviews": false
}
Cibler un autre pays ; les zones s'expriment alors dans ce pays :
{
"queries": ["plumber", "hvac"],
"country": "USA",
"zones": ["Texas", "Austin 30km"]
}
Colonnes optionnelles
departement/region: en France, dérivées du code postal ; dans tout autre pays, dérivées du GPS de l'établissement par reverse-geo mondial (adm2/adm1).
Requêtes Google Maps effectives = len(queries) × grid_points(zones). Rejeté à la soumission si coût supérieur au plafond per-job EF.
Outputs
Fichier résultat : CSV UTF-8, séparateur point-virgule, BOM (compatible Excel). Le même jeu de données est disponible en trois formats via l'endpoint de téléchargement.
| Colonne | Type | Description |
|---|---|---|
nom |
string | Nom de l'établissement affiché sur Google Maps. |
telephone |
string | Numéro de téléphone tel que listé. |
adresse |
string | Adresse (numéro et rue) telle qu'affichée dans la liste Maps. |
ville |
string | Ville, issue des données structurées de Google pour le lieu (exacte, arrondissements de Paris, Lyon et Marseille et communes à plusieurs codes postaux compris). Vide pour les fiches sans adresse chez Google. |
code_postal |
string | Code postal, issu de la même source Google que ville. |
site_web |
string | URL du site web public, si renseignée. |
lien_google_maps |
string | URL Google Maps de la fiche. |
note |
nombre | Note moyenne, de 0 à 5. Vide si la fiche n'en a pas. |
nb_avis |
entier | Nombre d'avis publics. Vide si inconnu. |
query |
string | Requête qui a produit la ligne. |
date_scraping |
string | Date et heure de collecte de la ligne. |
villeetcode_postalviennent des données structurées que Google fournit avec chaque résultat, pas d'un géocodage inverse : ils correspondent donc exactement à Google. La liste Maps n'affiche que la rue, c'est pourquoiadresseseule ne porte jamais la ville.
Le fichier ne contient ni catégorie, ni horaires d'ouverture, ni drapeau d'annuaire. Les sites web qui sont en réalité une fiche d'annuaire plutôt que le site propre de l'entreprise sont reconnus par dead_check (status = aggregator) et peuvent être écartés avec la règle exclude_aggregators de filter.
Colonnes optionnelles
Trois colonnes supplémentaires sont désactivées par défaut et s'activent par job via extra_columns (une liste). La sortie par défaut est rue + ville + code_postal.
Option dans extra_columns |
Ajoute | Description |
|---|---|---|
gps |
lat, lon |
Latitude et longitude exactes de l'établissement (coordonnées de Google, pas une approximation de grille). |
departement |
departement |
Nom du département (adm2). En France, déduit de code_postal ; ailleurs, déduit du GPS de l'établissement par géocodage inverse mondial. |
region |
region |
Nom de la région (adm1). En France, déduit de code_postal ; ailleurs, déduit du GPS de l'établissement par géocodage inverse mondial. |
Exemple de corps de requête : { "queries": ["plombier"], "zones": ["Paris 10km"], "extra_columns": ["gps", "departement", "region"] }.
Numéros étrangers
Une zone qui touche une frontière remonte aussi des établissements de l'autre côté : un scrap de Lille ramène des salons de Tournai, en Belgique, avec des numéros en +32.
exclude_foreign_phones, activé par défaut. Une fiche est écartée quand son numéro porte explicitement l'indicatif d'un autre pays que celui que vous avez choisi. Tout le reste est gardé :
| Fiche | Résultat |
|---|---|
Numéro écrit sans indicatif (03 20 53 00 86, 06 26 55 99 69) |
Gardée : c'est l'écriture des numéros du pays choisi. |
| Numéro avec l'indicatif du pays choisi | Gardée. |
Numéro avec l'indicatif d'un autre pays (+32 69 23 26 64 dans un scrap en France) |
Écartée. |
| Aucun numéro | Gardée. |
| Numéro illisible ou indicatif inconnu | Gardée. |
Le fonctionnement est le même dans tous les pays. Les indicatifs partagés par plusieurs pays (+1 pour les États-Unis, le Canada et les Caraïbes, +7 pour la Russie et le Kazakhstan, +44 pour le Royaume-Uni et les îles Anglo-Normandes) sont départagés par la plage du numéro, pas par l'indicatif seul. Les numéros des territoires d'outre-mer d'un pays comptent pour ce pays (Guadeloupe ou La Réunion pour la France, Porto Rico pour les États-Unis).
Les fiches écartées ne comptent pas dans stop_at, et le journal du job se termine par le nombre de fiches écartées de cette façon. Envoyez "exclude_foreign_phones": false (ou décochez Écarter les numéros étrangers dans les paramètres avancés) pour les garder.
Doublons
Une fiche = une ligne. Toujours, sans réglage pour le désactiver. Un établissement peut être à portée de plusieurs points de grille GPS et correspondre à plusieurs de vos requêtes, et l'URL Google de la fiche n'est pas une identité stable : elle encode aussi le contexte de recherche, donc deux captures du même lieu reviennent avec des URL différentes. Les lignes sont donc dédoublonnées sur le feature id 0x…:0x… que Google porte dans cette URL (repli sur nom + adresse normalisés s'il est absent). C'est une garantie de justesse, pas une préférence.
max_per_phone : le seul réglage. Des fiches différentes partagent parfois un numéro : un standard commun, un gérant multi-établissements, ou un réseau de fiches locales quasi identiques pointant vers un seul centre d'appel. Pour une chaîne ce sont de vrais établissements distincts ; pour de la prospection c'est un seul contact. L'arbitrage vous revient :
| Valeur | Comportement |
|---|---|
0 (défaut) |
Aucune limite : toutes les fiches sont gardées, quel que soit le numéro affiché. |
1 |
Une seule fiche par numéro ; la première trouvée gagne. |
2, 3, … (max 10) |
Jusqu'à N fiches par numéro. |
Les numéros sont comparés en E.164, donc +33 1 87 58 88 84 et 01 87 58 88 84 sont le même numéro ; le country du job fixe la région servant à parser les formats nationaux. Les fiches sans numéro exploitable ne sont jamais écartées par ce réglage.
Le quota s'applique sur tout le job, requêtes et zones confondues, et est conservé lors de la reprise d'un job annulé. Le dédoublonnage ne change pas les points de grille scrapés : aucun effet sur le coût EF ni sur la durée.
Formats : csv (original), json, xlsx. Choisi via ?format= sur l'endpoint de téléchargement.
Lifecycle
Cycle de vie standard : voir Jobs & lifecycle. Pendant l'exécution, l'événement SSE status transporte une charge query_stats de forme { "<query>": { "tiles": int, "with_results": int } }, mise à jour en temps réel pour exposer le taux de succès par requête.
Pipeline
| Field | Value |
|---|---|
needs |
null (module source : aucun CSV d'entrée requis) |
produces |
poi_list |
Modules typiques chaînés en aval d'un scrap :
emails: recherche les emails pro et personnels depuissite_web.socials: extrait les comptes réseaux sociaux depuissite_web.legal_ids: extrait SIREN/SIRET depuis le site de l'établissement (page mentions légales).reviews: collecte les fils d'avis complets depuislien_google_maps.techstack,dead_check,brand_assets,ads_intelligence: enrichissements au niveau site web, indexés sursite_web.
Endpoints
Endpoint dédié :
POST /api/jobs
Content-Type: application/json
{
"queries": ["plombier"],
"zones": ["75"],
"include_reviews": false
}
Endpoint générique (équivalent ; même payload, job_type déduit de la forme) :
POST /api/jobs
Content-Type: application/json
{
"job_type": "scrap",
"queries": ["plombier"],
"zones": ["75"]
}
Les deux réponses retournent l'objet JobPublic créé, incluant id, status, grid_points_count, ef_cost et output_filename.
Téléchargement :
GET /api/jobs/{job_id}/download?format=csv|json|xlsx
Limits
Quotas globaux de la plateforme : voir /docs/fr/concepts/limits. Plafonds spécifiques au module :
| Limit | Value |
|---|---|
| Nombre maximum de requêtes par job | 20 |
| Nombre maximum de zones par job | 50 |
| Longueur maximum d'une requête | 200 caractères |
| Coût maximum par job | 5 EF par défaut (par utilisateur, réglable jusqu'à 50) |
| Vérification email | Requise sur le compte avant création d'un job scrap. |
Errors
| Scenario | HTTP | Resolution |
|---|---|---|
| Zone non reconnue | 400 | Inspecter le tableau errors dans le corps de réponse. Vérifier que la zone est orthographiée telle qu'elle existe dans le country sélectionné (état/région, comté/département, "Ville 30km", ou nom du pays). Pour la France, codes INSEE/département/postaux et "France" fonctionnent aussi. Quand un nom proche existe, l'erreur l'indique (suggestion). |
| Aucun point de grille résolu | 400 | L'ensemble des zones est vide après résolution : élargir la sélection. |
| Quota EF dépassé | 400 | Réduire le nombre de requêtes ou rétrécir les zones jusqu'à ce que l'EF estimé tienne dans votre seuil par job (5 par défaut, réglable jusqu'à 50 dans Réglages). |
| Email non vérifié | 403 | Vérifier l'email du compte avant de créer un job scrap. |
| Aucun worker disponible | Le job reste en pending jusqu'à libération du pool multi-proxy partagé. Un seul job multi-proxy tourne à la fois sur l'ensemble de la plateforme. |
|
| Job échoué en cours | Un CSV partiel est conservé. Un POST /api/jobs/{id}/resume crée un job de relance qui saute les points de grille déjà traités et n'est facturé que sur le reliquat. |
|
| Durée maximale atteinte | Un job s'exécute pendant 24 heures au plus. Il s'arrête alors en conservant son CSV partiel et un job de suite est remis en file automatiquement pour les points de grille restants, facturé sur le seul reliquat. Rien à faire : suivre le nouveau job, relié par source_job_id. |
|
| Téléchargement expiré | 410 | Les fichiers résultats ont une fenêtre de rétention : relancer le job ou chaîner depuis une source fraîche. |
Les requêtes refusées par Google Maps remontent dans dead_queries sur l'objet job.
Sources de données & attribution
La résolution des zones et le reverse-geocoding mondiaux reposent sur des jeux de données ouverts :
Frontières administratives mondiales © geoBoundaries (CC BY 4.0) · Villes © GeoNames (CC BY 4.0).