Le moteur de recherche personnalisé Google (CSE) est fermé aux nouvelles inscriptions et sa capacité de recherche sur l'ensemble du Web prend fin le 1er janvier 2027. Si vous lisez ceci, votre date limite de migration approche. Voici le guide de migration d'urgence : remplacez vos appels CSE par des appels API Scavio en moins d'une heure. Scavio fournit des résultats équivalents à Google ainsi qu'Amazon, YouTube, Walmart, Reddit et TikTok depuis le même point d'accès. À 0,005 $ par requête avec 250 crédits mensuels gratuits, vous économisez probablement de l'argent par rapport au tarif CSE.
Prérequis
- Une intégration CSE fonctionnelle que vous devez remplacer
- Python 3.9+ ou Node.js 18+ installé
- Une clé API Scavio depuis scavio.dev (niveau gratuit : 250 crédits/mois)
- 30 à 60 minutes pour la migration
Parcours
Étape 1: Faites correspondre les champs de réponse de votre CSE à Scavio
La différence cruciale : CSE utilise GET avec des paramètres de requête, Scavio utilise POST avec un corps JSON. Mappage des champs de réponse : items -> organic_results, searchInformation -> search_metadata, queries -> non nécessaire.
# CSE response structure -> Scavio equivalent
field_mapping = {
# CSE field -> Scavio field
'items': 'organic_results',
'items[].title': 'organic_results[].title',
'items[].link': 'organic_results[].link',
'items[].snippet': 'organic_results[].snippet',
'items[].pagemap': 'organic_results[].rich_snippet',
'searchInformation.totalResults': 'search_metadata.total_results',
'spelling.correctedQuery': 'search_metadata.spelling_fix',
'queries.nextPage': 'pagination.next',
}
# CSE parameter mapping
param_mapping = {
# CSE param -> Scavio equivalent
'q': 'query',
'num': 'num_results',
'gl': 'country_code',
'hl': 'language',
'start': 'page (via pagination)',
'siteSearch': 'query prefix: site:domain.com',
'dateRestrict': 'query suffix: after:YYYY-MM-DD',
}
for cse, scavio in field_mapping.items():
print(f'{cse:45s} -> {scavio}')Étape 2: Écrivez la fonction de remplacement direct
Créez une fonction avec la même signature que votre wrapper CSE. Elle gère le changement de méthode HTTP (GET vers POST) et le renommage des champs de réponse.
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def google_search(query: str, num: int = 10, country: str = 'us', **kwargs) -> dict:
"""Drop-in CSE replacement. Same return shape as CSE response."""
# Handle site restriction
site = kwargs.get('siteSearch', '')
if site:
query = f'site:{site} {query}'
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': country, 'num_results': num})
resp.raise_for_status()
data = resp.json()
# Return CSE-compatible structure
organic = data.get('organic_results', [])
return {
'items': [{'title': r['title'], 'link': r['link'],
'snippet': r.get('snippet', ''),
'displayLink': r['link'].split('/')[2] if '/' in r['link'] else ''}
for r in organic],
'searchInformation': {'totalResults': str(len(organic))}
}
result = google_search('python tutorial 2026')
print(f"Got {len(result['items'])} results")
for item in result['items'][:3]:
print(f" {item['title']}")Étape 3: Recherchez et remplacez tous les appels CSE
Parcourez votre codebase à la recherche d'appels API CSE et remplacez-les. Les schémas courants incluent les appels HTTP directs, l'utilisation de la bibliothèque cliente Google API et les wrappers CSE tiers.
# Pattern 1: Direct requests call to CSE
# BEFORE:
# resp = requests.get('https://www.googleapis.com/customsearch/v1',
# params={'key': CSE_KEY, 'cx': CSE_ID, 'q': query})
# AFTER:
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': 10})
# Pattern 2: Google API Client Library
# BEFORE:
# from googleapiclient.discovery import build
# service = build('customsearch', 'v1', developerKey=CSE_KEY)
# result = service.cse().list(q=query, cx=CSE_ID).execute()
# AFTER:
result = google_search(query) # Use the wrapper from step 2
# Pattern 3: Environment variable cleanup
# Remove: GOOGLE_CSE_KEY, GOOGLE_CSE_ID
# Add: SCAVIO_API_KEY
import os
assert os.environ.get('SCAVIO_API_KEY'), 'Set SCAVIO_API_KEY env var'
print('Environment configured')Étape 4: Effectuez une validation côte à côte
Testez vos requêtes les plus courantes via les deux chemins, ancien et nouveau. Vérifiez que le nombre de résultats, les premiers résultats et tous les champs que vous analysez en aval sont corrects.
def validate_migration(queries: list[str]):
print('Migration Validation Report')
print('=' * 50)
all_pass = True
for q in queries:
result = google_search(q)
items = result.get('items', [])
checks = {
'has_results': len(items) > 0,
'has_titles': all(i.get('title') for i in items),
'has_links': all(i.get('link') for i in items),
'has_snippets': all(i.get('snippet') for i in items[:3]),
}
status = 'PASS' if all(checks.values()) else 'FAIL'
if status == 'FAIL':
all_pass = False
print(f'\n[{status}] {q}')
print(f' Results: {len(items)}')
for check, passed in checks.items():
print(f' {check}: {"ok" if passed else "FAILED"}')
print(f'\nOverall: {"ALL PASS" if all_pass else "SOME FAILURES"}')
validate_migration([
'python web framework 2026',
'machine learning tutorial',
'best laptop for coding',
])Étape 5: Mettez à jour l'environnement et déployez
Supprimez les identifiants CSE, ajoutez la clé Scavio et déployez. Le niveau gratuit vous offre 250 requêtes par mois pour vérifier en production avant de vous engager dans un plan payant.
# .env file update
# REMOVE these:
# GOOGLE_CSE_API_KEY=AIza...
# GOOGLE_CSE_ENGINE_ID=017...
# ADD this:
# SCAVIO_API_KEY=your_key_here
# Verify the migration
import os
def verify_deployment():
key = os.environ.get('SCAVIO_API_KEY')
assert key, 'SCAVIO_API_KEY not set'
# Quick health check
result = google_search('test query')
assert len(result['items']) > 0, 'No results returned'
print('Migration verified:')
print(f' API key: {key[:8]}...')
print(f' Test query returned {len(result["items"])} results')
print(f' Cost per request: $0.005')
print(f' Free tier: 250 requests/month')
print(f' Paid plan: $30/month for 7,000 credits')
# Cost comparison
print(f'\nCSE was: $5 per 1,000 queries')
print(f'Scavio: $5 per 1,000 queries (same price, more platforms)')
verify_deployment()Exemple Python
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def google_search(query, num=10, **kw):
site = kw.get('siteSearch', '')
if site:
query = f'site:{site} {query}'
resp = requests.post('https://api.scavio.dev/api/v1/search',
headers={'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json'},
json={'query': query, 'country_code': 'us', 'num_results': num})
resp.raise_for_status()
results = resp.json().get('organic_results', [])
return {'items': [{'title': r['title'], 'link': r['link'],
'snippet': r.get('snippet', '')} for r in results]}
result = google_search('best python frameworks 2026')
for item in result['items'][:5]:
print(f"{item['title']}\n {item['link']}")
print(f'\nCost: ${len(result["items"]) * 0.005:.3f} for this search')Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function googleSearch(query, { num = 10, siteSearch = '' } = {}) {
if (siteSearch) query = `site:${siteSearch} ${query}`;
const resp = await fetch('https://api.scavio.dev/api/v1/search', {
method: 'POST',
headers: { 'x-api-key': SCAVIO_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ query, country_code: 'us', num_results: num })
});
const data = await resp.json();
return { items: (data.organic_results || []).map(r => ({
title: r.title, link: r.link, snippet: r.snippet || ''
}))};
}
googleSearch('best python frameworks 2026').then(r => {
r.items.slice(0, 5).forEach(i => console.log(`${i.title}\n ${i.link}`));
});Sortie attendue
Migration Validation Report
==================================================
[PASS] python web framework 2026
Results: 10
has_results: ok
has_titles: ok
has_links: ok
has_snippets: ok
[PASS] machine learning tutorial
Results: 10
Overall: ALL PASS
Migration verified:
API key: sk-12345...
Test query returned 10 results
Cost per request: $0.005