Google 自定义搜索引擎已关闭新注册,其搜索整个网络功能将于 2027 年 1 月 1 日结束。如果您正在阅读本文,则说明您的迁移截止日期即将到来。这是紧急迁移指南:在一小时内将 CSE 调用替换为 Scavio API 调用。 Scavio 提供与 Google 等效的结果,以及来自同一端点的 Amazon、YouTube、Walmart、Reddit 和 TikTok。每个请求 0.005 美元,每月有 250 个免费积分,与 CSE 定价相比,您可能会省钱。
前置条件
- 您需要替换的可用 CSE 集成
- 安装了 Python 3.9+ 或 Node.js 18+
- 来自 scavio.dev 的 Scavio API 密钥(免费套餐:250 积分/月)
- 迁移时间为 30-60 分钟
操作指南
步骤 1: 将您的 CSE 响应字段映射到 Scavio
关键区别:CSE 使用带有查询参数的 GET,而 Scavio 使用带有 JSON 正文的 POST。响应字段映射:项目 -> Organic_results、searchInformation -> search_metadata、查询 -> 不需要。
# 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}')步骤 2: 编写直接替换函数
创建一个与 CSE 包装器具有相同签名的函数。这处理 HTTP 方法更改(GET 到 POST)和响应字段重命名。
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']}")步骤 3: 查找并替换所有 CSE 调用
在您的代码库中搜索 CSE API 调用并交换它们。常见模式包括直接 HTTP 调用、Google API 客户端库使用和第三方 CSE 包装器。
# 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')步骤 4: 运行并行验证
通过旧路径和新路径测试最常见的查询。验证结果计数、顶部结果以及您在下游解析的任何字段是否都正确。
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',
])步骤 5: 更新环境并部署
删除 CSE 凭据,添加 Scavio 密钥并部署。免费套餐每月为您提供 250 个请求,以便您在投入付费计划之前在生产中进行验证。
# .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()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')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}`));
});预期输出
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