求助解决Google Custom Search API调用403 Forbidden错误问题
问题排查与解决方案
从错误栈来看,你的403 Forbidden错误是在下载图片阶段触发的(来自urllib.request.urlretrieve),而非Google Custom Search API请求本身。以下是具体排查方向和修复方案:
1. 规避图片源站的反爬拦截
绝大多数图片网站会检测请求的User-Agent字段,默认的urllib请求使用的是爬虫标识,容易被拦截。修改下载逻辑,添加模拟浏览器的请求头:
方案一:改用requests库下载(推荐)
# 替换原有的图片下载代码段 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'} for i, item in enumerate(results.get('items', []), start=1): link = item['link'] try: img_response = requests.get(link, headers=headers, timeout=10) if img_response.status_code == 200: with open(f'swieci-images/{filename}-{i}.png', 'wb') as f: f.write(img_response.content) else: print(f"Failed to download {link}: Status code {img_response.status_code}") except Exception as e: print(f"Error downloading {link}: {str(e)}")
方案二:修改urllib的请求头
# 替换原有的urllib.request.urlretrieve代码 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'} for i, item in enumerate(results.get('items', []), start=1): link = item['link'] try: req = urllib.request.Request(link, headers=headers) with urllib.request.urlopen(req, timeout=10) as response, open(f'swieci-images/{filename}-{i}.png', 'wb') as out_file: out_file.write(response.read()) except Exception as e: print(f"Error downloading {link}: {str(e)}")
2. 确保API请求参数的正确性
手动拼接URL可能因特殊字符(如波兰语字符、空格)导致编码错误,改用requests的params参数自动处理编码:
# 替换原有的API请求代码段 params = { 'q': query, 'num': 3, 'start': 1, 'lr': 'lang_pl', 'safe': 'off', 'cx': cx, 'searchType': 'image', 'key': api_key } response = requests.get("https://www.googleapis.com/customsearch/v1", params=params)
3. 检查Google Custom Search API配额
虽然当前错误不是API直接返回,但仍需确认配额状态:
- 登录Google Cloud Console,进入对应项目的「API和服务」→「配额」页面,查看Custom Search API的剩余请求次数。若配额耗尽,API会返回403,此时需等待次日配额重置或启用付费额度。
4. 增强错误排查能力
在脚本中添加API请求失败的详细日志,方便定位问题:
# 在API请求后添加 if response.status_code != 200: print(f"API request failed for query '{query}': {response.status_code} - {response.text}") continue
内容的提问来源于stack exchange,提问作者Michał
相关产品推荐
相关产品推荐

