Google Maps est l'une des sources les plus riches de données sur les entreprises locales pour la génération de leads B2B. Un pipeline n8n peut automatiser le processus : rechercher des entreprises dans une niche et un emplacement cibles, extraire les coordonnées de leurs sites web, valider les e-mails et envoyer les leads qualifiés vers votre CRM. Ce tutoriel construit le pipeline complet en utilisant le nœud HTTP Request de n8n avec l'API de recherche Scavio. Chaque requête de recherche coûte 0,005 $, ce qui rend une extraction de 500 entreprises à 2,50 $.
Prérequis
- Instance n8n en cours d'exécution (auto-hébergée ou cloud)
- Une clé API Scavio depuis scavio.dev
- Familiarité de base avec l'éditeur de workflow n8n
- Un CRM ou un tableur pour recevoir les leads
Parcours
Étape 1: Configurer le nœud de requête de recherche
Créez un nœud HTTP Request dans n8n qui interroge l'API Scavio pour obtenir des résultats Google Maps. Utilisez le paramètre maps platform pour obtenir des listes d'entreprises avec adresses et numéros de téléphone.
// n8n HTTP Request Node configuration:
// Method: POST
// URL: https://api.scavio.dev/api/v1/search
// Headers:
// x-api-key: {{ $env.SCAVIO_API_KEY }}
// Content-Type: application/json
// Body (JSON):
{
"query": "plumbers in Austin TX",
"platform": "maps",
"country_code": "us"
}Étape 2: Boucler sur plusieurs requêtes de recherche
Utilisez un nœud SplitInBatches pour parcourir une liste de niches et d'emplacements. Alimentez chaque combinaison dans le nœud de recherche.
// Generate query list in a Code node:
const niches = ['plumbers', 'electricians', 'HVAC contractors'];
const cities = ['Austin TX', 'Dallas TX', 'Houston TX'];
const queries = [];
for (const niche of niches) {
for (const city of cities) {
queries.push({ json: { query: `${niche} in ${city}` } });
}
}
return queries;
// Output: 9 query combinationsÉtape 3: Extraire les données des entreprises à partir des résultats
Analysez les résultats Maps pour extraire le nom, l'adresse, le téléphone, le site web et la note de l'entreprise. Utilisez un nœud Code pour normaliser les données.
// n8n Code node to extract business data:
const results = $input.first().json;
const businesses = (results.local_results || []).map(b => ({
name: b.title || '',
address: b.address || '',
phone: b.phone || '',
website: b.website || '',
rating: b.rating || 0,
reviews: b.reviews || 0,
query: results.search_metadata?.query || ''
}));
return businesses
.filter(b => b.website)
.map(b => ({ json: b }));Étape 4: Trouver les adresses e-mail à partir des sites web
Pour chaque entreprise disposant d'un site web, recherchez leur page de contact pour trouver des adresses e-mail. Utilisez une deuxième requête de recherche ciblant le domaine.
// n8n HTTP Request node for email discovery:
// URL: https://api.scavio.dev/api/v1/search
// Body:
{
"query": "site:{{ $json.website }} contact email",
"country_code": "us"
}
// Then in a Code node, extract emails from snippets:
const data = $input.first().json;
const snippets = (data.organic_results || [])
.map(r => r.snippet || '')
.join(' ');
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
const emails = [...new Set(snippets.match(emailRegex) || [])];
return [{ json: { ...($input.first().json), emails } }];Étape 5: Envoyer vers CRM ou Google Sheets
Envoyez les leads validés vers votre CRM. Cet exemple utilise le nœud Google Sheets mais fonctionne avec HubSpot, Pipedrive ou tout CRM disposant d'une intégration n8n.
// n8n Google Sheets node configuration:
// Operation: Append Row
// Sheet: Lead Pipeline
// Columns mapping:
// A: {{ $json.name }}
// B: {{ $json.address }}
// C: {{ $json.phone }}
// D: {{ $json.website }}
// E: {{ $json.emails[0] || '' }}
// F: {{ $json.rating }}
// G: {{ $json.reviews }}
// H: {{ $json.query }}
// I: {{ new Date().toISOString() }}
// Cost summary for 9 queries (3 niches x 3 cities):
// Search queries: 9 x $0.005 = $0.045
// Email discovery: ~50 domains x $0.005 = $0.25
// Total: ~$0.30 for 50+ validated leadsExemple Python
import os, re, requests, time
API_KEY = os.environ['SCAVIO_API_KEY']
ENDPOINT = 'https://api.scavio.dev/api/v1/search'
def search(body: dict) -> dict:
resp = requests.post(ENDPOINT,
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json=body)
resp.raise_for_status()
return resp.json()
def extract_leads(niche: str, city: str) -> list:
data = search({'query': f'{niche} in {city}', 'platform': 'maps', 'country_code': 'us'})
leads = []
for b in data.get('local_results', []):
if not b.get('website'):
continue
# Find emails from website
email_data = search({'query': f'site:{b["website"]} contact email', 'country_code': 'us'})
snippets = ' '.join(r.get('snippet', '') for r in email_data.get('organic_results', []))
emails = list(set(re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', snippets)))
leads.append({'name': b.get('title'), 'phone': b.get('phone'),
'website': b['website'], 'emails': emails})
time.sleep(0.3)
return leads
leads = extract_leads('plumbers', 'Austin TX')
for lead in leads[:5]:
print(f'{lead["name"]}: {lead["emails"] or "no email found"}')Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
async function search(body) {
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
return resp.json();
}
async function extractLeads(niche, city) {
const data = await search({ query: `${niche} in ${city}`, platform: 'maps', country_code: 'us' });
const leads = [];
for (const b of (data.local_results || []).filter(b => b.website)) {
const emailData = await search({ query: `site:${b.website} contact email`, country_code: 'us' });
const text = (emailData.organic_results || []).map(r => r.snippet || '').join(' ');
const emails = [...new Set(text.match(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g) || [])];
leads.push({ name: b.title, phone: b.phone, website: b.website, emails });
}
return leads;
}
extractLeads('plumbers', 'Austin TX').then(leads => {
leads.slice(0, 5).forEach(l => console.log(`${l.name}: ${l.emails.length ? l.emails[0] : 'no email'}`));
});Sortie attendue
Austin Plumbing Pros: info@austinplumbingpros.com
Capital City Plumbers: contact@capitalcityplumbers.com
Reliable Plumbing Austin: no email found
Lone Star Plumbing: service@lonestarplumbing.com
Premier Plumbing Co: no email found
Cost: 9 search queries + ~50 email lookups = ~$0.30 total