Les annuaires B2B comme Clutch, G2 et les listes spécifiques à un secteur sont de riches sources de données d'entreprise pour la prospection sortante. Au lieu de construire des scrapers navigateurs fragiles qui cassent lorsque la mise en page des annuaires change, vous pouvez rechercher des listes d'annuaires via une API de recherche et extraire des données structurées à partir des extraits SERP. Cette approche est plus rapide, moins chère et plus facile à maintenir. Ce tutoriel construit un pipeline n8n qui interroge les annuaires, extrait les informations sur les entreprises et produit une liste de prospects propres. Chaque recherche coûte 0,005 $ via Scavio.
Prérequis
- Instance n8n en cours d'exécution (auto-hébergée ou cloud)
- Une clé API Scavio depuis scavio.dev
- Secteur ou niche cible à prospecter
- Google Sheets ou CRM pour la sortie
Parcours
Étape 1: Définir les requêtes de recherche d'annuaire
Créez des requêtes de recherche qui ciblent les listes d'annuaires B2B. Le modèle est : site:directory.com + niche + location. Cela récupère uniquement les pages d'annuaire, et non des sites web aléatoires.
// n8n Code node to generate targeted queries:
const directories = [
{ name: 'clutch', query: 'site:clutch.co' },
{ name: 'g2', query: 'site:g2.com' },
{ name: 'goodfirms', query: 'site:goodfirms.co' }
];
const niches = ['marketing agency', 'web development company', 'IT consulting'];
const queries = [];
for (const dir of directories) {
for (const niche of niches) {
queries.push({
json: {
directory: dir.name,
searchQuery: `${dir.query} ${niche}`,
niche
}
});
}
}
return queries; // 9 targeted directory queriesÉtape 2: Exécuter les requêtes de recherche via une requête HTTP
Pour chaque requête, appelez l'API Scavio pour obtenir les résultats de listes d'annuaire. Les résultats organiques contiennent les noms d'entreprise, descriptions et évaluations dans les extraits.
// n8n HTTP Request node:
// Method: POST
// URL: https://api.scavio.dev/api/v1/search
// Headers: x-api-key: {{ $env.SCAVIO_API_KEY }}
// Body:
{
"query": "{{ $json.searchQuery }}",
"country_code": "us"
}Étape 3: Analyser les données d'entreprise des résultats SERP
Extrayez les noms d'entreprise, URL et descriptions des résultats organiques. Les pages d'annuaire ont des formats de titre prévisibles qui peuvent être analysés.
// n8n Code node to parse directory listings:
const data = $input.first().json;
const companies = (data.organic_results || []).map(r => {
// Clutch titles: "Company Name - Reviews, Cost & More"
// G2 titles: "Company Name Reviews 2026"
const name = r.title.split(' - ')[0].split(' Reviews')[0].trim();
return {
name,
url: r.link,
description: r.snippet || '',
directory: $('Code').first().json.directory,
niche: $('Code').first().json.niche
};
}).filter(c => c.name.length > 2 && c.name.length < 100);
return companies.map(c => ({ json: c }));Étape 4: Dédoublonner et enrichir avec une recherche de site web
Supprimez les doublons d'entreprises entre les annuaires et enrichissez éventuellement avec une recherche directe pour chaque entreprise afin de trouver leur site web réel et leurs coordonnées.
// Dedup in a Code node:
const seen = new Set();
const unique = [];
for (const item of $input.all()) {
const key = item.json.name.toLowerCase();
if (!seen.has(key)) {
seen.add(key);
unique.push(item);
}
}
return unique;
// Then enrich each with a second search:
// HTTP Request node:
// Body:
{
"query": "{{ $json.name }} company website contact",
"country_code": "us"
}Étape 5: Exporter vers Google Sheets avec suivi des coûts
Écrivez les prospects nettoyés dans une Google Sheet. Ajoutez une colonne de coût pour savoir exactement ce que l'extraction a coûté.
// Final Code node before Google Sheets:
const leads = $input.all().map((item, i) => ({
json: {
...item.json,
extractedAt: new Date().toISOString(),
estimatedCost: ((i + 1) * 0.005).toFixed(3)
}
}));
const totalCost = (leads.length * 0.005).toFixed(2);
console.log(`Extracted ${leads.length} leads, cost: $${totalCost}`);
return leads;
// Google Sheets node: Append to "B2B Leads" sheet
// Total cost: 9 directory queries + ~50 enrichment queries = ~$0.30Exemple Python
import os, requests, time
API_KEY = os.environ['SCAVIO_API_KEY']
def search(query: str) -> dict:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us'})
return resp.json()
def scrape_directory(directory_site: str, niche: str) -> list:
data = search(f'site:{directory_site} {niche}')
companies = []
for r in data.get('organic_results', []):
name = r['title'].split(' - ')[0].split(' Reviews')[0].strip()
companies.append({'name': name, 'url': r['link'],
'snippet': r.get('snippet', ''), 'directory': directory_site})
return companies
def main():
directories = ['clutch.co', 'g2.com', 'goodfirms.co']
all_leads = []
seen = set()
for d in directories:
companies = scrape_directory(d, 'marketing agency')
for c in companies:
if c['name'].lower() not in seen:
seen.add(c['name'].lower())
all_leads.append(c)
time.sleep(0.3)
print(f'Found {len(all_leads)} unique companies')
for lead in all_leads[:5]:
print(f' {lead["name"]} ({lead["directory"]})')
if __name__ == '__main__':
main()Exemple JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;
async function search(query) {
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({ query, country_code: 'us' })
});
return resp.json();
}
async function main() {
const directories = ['clutch.co', 'g2.com', 'goodfirms.co'];
const seen = new Set();
const leads = [];
for (const dir of directories) {
const data = await search(`site:${dir} marketing agency`);
for (const r of data.organic_results || []) {
const name = r.title.split(' - ')[0].split(' Reviews')[0].trim();
if (!seen.has(name.toLowerCase())) {
seen.add(name.toLowerCase());
leads.push({ name, url: r.link, directory: dir });
}
}
}
console.log(`Found ${leads.length} unique companies`);
leads.slice(0, 5).forEach(l => console.log(` ${l.name} (${l.directory})`));
}
main().catch(console.error);Sortie attendue
Found 27 unique companies across 3 directories
WebFX (clutch.co)
Ignite Digital (clutch.co)
SmartSites (g2.com)
Thrive Internet Marketing (goodfirms.co)
Disruptive Advertising (g2.com)
Cost: 3 directory queries = $0.015
With enrichment: ~$0.15 total