Google Custom Search Engine a fermé les nouvelles inscriptions et mettra fin à sa fonction de recherche sur le Web entier le 1er janvier 2027. Si votre application repose sur CSE pour la recherche web, vous avez besoin d’un plan de migration dès maintenant. Scavio propose un remplacement direct qui couvre Google, Amazon, YouTube, Walmart, Reddit et TikTok depuis un seul point de terminaison POST à 0,005 $ par requête. Ce tutoriel vous guide à travers chaque étape : auditer votre utilisation actuelle de CSE, mapper les paramètres CSE vers leurs équivalents Scavio, mettre à jour votre code et valider les résultats.
Prérequis
- Une intégration Google CSE existante que vous devez migrer
- Python 3.9+ ou Node.js 18+ installé
- Une clé API Scavio depuis scavio.dev
- Accès à votre clé API CSE actuelle et à votre identifiant de moteur de recherche
Parcours
Étape 1: Auditez votre utilisation actuelle de CSE
Avant de migrer, documentez chaque appel CSE dans votre code. Notez les paramètres de requête que vous utilisez, les champs de réponse que vous analysez et votre volume mensuel de requêtes.
# Typical Google CSE call you need to replace
import requests
CSE_KEY = 'your-google-api-key'
CSE_ID = 'your-search-engine-id'
def old_cse_search(query: str) -> list:
resp = requests.get('https://www.googleapis.com/customsearch/v1', params={
'key': CSE_KEY, 'cx': CSE_ID, 'q': query, 'num': 10
})
items = resp.json().get('items', [])
return [{'title': i['title'], 'link': i['link'],
'snippet': i.get('snippet', '')} for i in items]
# Document what you actually use from the response
results = old_cse_search('best python frameworks 2026')
for r in results:
print(f"{r['title']} -> {r['link']}")Étape 2: Créez la fonction de remplacement Scavio
Remplacez la requête GET CSE par une requête POST Scavio. La structure de réponse se mappe proprement : items devient organic_results, et chaque résultat possède les champs title, link et snippet.
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def scavio_search(query: str, num: int = 10) -> list:
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 [{'title': r['title'], 'link': r['link'],
'snippet': r.get('snippet', '')} for r in results]
results = scavio_search('best python frameworks 2026')
for r in results:
print(f"{r['title']} -> {r['link']}")Étape 3: Mappez les paramètres spécifiques à CSE
Si vous utilisez des fonctionnalités CSE comme la restriction de site, la plage de dates ou le filtrage par langue, mappez-les vers des paramètres de requête Scavio ou une syntaxe de requête.
# CSE site restriction -> Scavio query syntax
# Old: params={'siteSearch': 'reddit.com', 'q': query}
# New: prepend site: to query
def search_site(query: str, site: str) -> list:
return scavio_search(f'site:{site} {query}')
# CSE country -> Scavio country_code
def search_country(query: str, country: str = 'us') -> list:
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': 10})
return resp.json().get('organic_results', [])
# CSE date restrict -> Scavio query syntax
def search_recent(query: str) -> list:
return scavio_search(f'{query} after:2026-01-01')
print('Site search:', len(search_site('python tutorial', 'docs.python.org')))
print('Country search:', len(search_country('AI news', 'gb')))
print('Recent search:', len(search_recent('AI frameworks')))Étape 4: Créez un wrapper de compatibilité pour un échange sans interruption
Créez un wrapper qui correspond exactement au format de réponse CSE afin que le code aval n'ait pas besoin de modifications. Cela vous permet de changer de backend sans toucher aux consommateurs.
def cse_compatible_search(query: str, **kwargs) -> dict:
"""Drop-in replacement that returns CSE-format response."""
num = kwargs.get('num', 10)
results = scavio_search(query, num=num)
# Return CSE-compatible response shape
return {
'searchInformation': {
'totalResults': str(len(results)),
'searchTime': 0.3
},
'items': [{
'title': r['title'],
'link': r['link'],
'snippet': r['snippet'],
'displayLink': r['link'].split('/')[2] if '/' in r['link'] else ''
} for r in results]
}
# Your existing code works unchanged
response = cse_compatible_search('best python frameworks 2026')
for item in response['items']:
print(f"{item['title']} ({item['displayLink']})")
print(f"Total: {response['searchInformation']['totalResults']}")Étape 5: Validez les résultats et comparez la qualité
Exécutez les deux API en parallèle pendant une semaine pour vérifier la qualité des résultats avant de basculer complètement. Consignez toute divergence.
import json
from datetime import datetime
def compare_search(query: str) -> dict:
scavio_results = scavio_search(query, num=5)
scavio_urls = set(r['link'] for r in scavio_results)
comparison = {
'query': query,
'timestamp': datetime.now().isoformat(),
'scavio_count': len(scavio_results),
'scavio_top_3': [r['title'] for r in scavio_results[:3]],
}
return comparison
test_queries = [
'best python web framework 2026',
'how to deploy fastapi production',
'typescript vs python performance'
]
for q in test_queries:
result = compare_search(q)
print(f"Query: {q}")
print(f" Scavio: {result['scavio_count']} results")
print(f" Top 3: {result['scavio_top_3']}")
print()Exemple Python
import os, requests
SCAVIO_KEY = os.environ['SCAVIO_API_KEY']
def search(query, num=10):
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()
return resp.json().get('organic_results', [])
def cse_compat(query, **kw):
results = search(query, num=kw.get('num', 10))
return {'items': [{'title': r['title'], 'link': r['link'],
'snippet': r.get('snippet', '')} for r in results]}
resp = cse_compat('python frameworks 2026')
for item in resp['items']:
print(f"{item['title']} -> {item['link']}")
print(f'Total: {len(resp["items"])} results at $0.005')Exemple JavaScript
const SCAVIO_KEY = process.env.SCAVIO_API_KEY;
async function search(query, num = 10) {
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 })
});
return (await resp.json()).organic_results || [];
}
async function cseCompat(query) {
const results = await search(query);
return { items: results.map(r => ({ title: r.title, link: r.link, snippet: r.snippet || '' })) };
}
cseCompat('python frameworks 2026').then(resp => {
resp.items.forEach(i => console.log(`${i.title} -> ${i.link}`));
console.log(`Total: ${resp.items.length} results at $0.005`);
});Sortie attendue
best python frameworks 2026 -> https://example.com/...
Django vs FastAPI in 2026: Which Should You Choose?
-> https://blog.example.com/django-vs-fastapi-2026
Top 10 Python Web Frameworks for Production
-> https://example.com/top-python-frameworks
Total: 10 results at $0.005