Google App Engine中Python Requests代理请求API出现乱码问题
问题描述
Python脚本在本地运行正常,但部署到Google App Engine(GAE)后,通过HTTPS代理访问带Cloudflare防护的GraphQL API时返回乱码。脚本核心逻辑:
- 从
proxies.txt随机选取美国地区的HTTPS代理 - 用
https://api.ipify.org/?format=json验证代理可用性,GAE上此请求及访问https://example.com均正常 - 携带指定headers、payload向目标API发送GET请求时,返回乱码内容
相关代码文件
main.py
import random import requests lines = open(r'proxies.txt').read().splitlines() # 随机选取可用的美国代理 while True: line = random.choice(lines) if line.split(':')[2] != "United States": continue proxy = line.split(':')[0] + ':' + line.split(':')[1] website_url = 'https://api.ipify.org/?format=json' proxy_dict = { 'https': f'https://{proxy}' } try: response = requests.get(website_url, proxies=proxy_dict, timeout=2, verify=False) print(f'\x1b[38;5;47mProxy {proxy} 可正常处理HTTPS请求。') print("当前IP: " , response.text , "\n\x1b[1;0m") break except requests.exceptions.RequestException as e: print(f'\x1b[38;5;3m测试代理 {proxy} 时出错: {str(e)}\x1b[1;0m') url = "目标API地址" headers = { "Content-Type": "application/json", "Host": "prd-usta-kube-tournaments.clubspark.pro", "Sec-Ch-Ua": "\"Chromium\";v=\"123\", \"Not:A-Brand\";v=\"8\"", "Accept": "*/*", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.88 Safari/537.36", "Sec-Ch-Ua-Platform": "\"Windows\"", "Origin": "https://playtennis.usta.com", "Referer": "https://playtennis.usta.com/", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "en-US,en;q=0.9", "Priority": "u=1, i" } payload = { # 请求负载内容 } cookies = {} r = requests.get(url, json=payload, headers=headers, cookies=cookies, verify=False, proxies=proxy_dict) response.encoding = 'utf-8' # 此处编码设置无效,对应对象错误 print(r.text)
proxies.txt
https代理IP:端口:United States
GAE上的乱码示例
��������tu�S7���.��JU�,ӳ"#<;,��!!A�L��:����#�;��r�6��)�Vj���<hh(����O�RAA�����3Q��0>K.����0�
解决思路与方案
1. 修复编码设置错误
代码中response.encoding = 'utf-8'是给代理验证请求的response对象设置编码,而非目标API的r对象,完全无效。需改为:
r.encoding = 'utf-8'
2. 处理响应压缩编码
headers中设置了Accept-Encoding: gzip, deflate, br,但GAE环境下requests可能未自动解码压缩内容,导致输出原始二进制乱码。两种解决方式:
- 直接移除
Accept-Encoding头,让服务器返回未压缩文本 - 手动解码压缩响应:
import gzip import brotli from io import BytesIO # 解码gzip压缩 if r.headers.get('Content-Encoding') == 'gzip': buffer = BytesIO(r.content) gzip_file = gzip.GzipFile(fileobj=buffer) decoded_content = gzip_file.read().decode('utf-8') print(decoded_content) # 解码brotli压缩 elif r.headers.get('Content-Encoding') == 'br': decoded_content = brotli.decompress(r.content).decode('utf-8') print(decoded_content) else: print(r.text)
3. 规避Cloudflare检测
Cloudflare可能识别GAE环境特征,返回混淆内容:
- GraphQL接口通常用POST请求,改为POST尝试:
r = requests.post(url, json=payload, headers=headers, cookies=cookies, verify=False, proxies=proxy_dict)
- 调整
User-Agent为更贴近真实浏览器的字符串,或添加Connection: keep-alive等真实浏览器headers - 尝试在请求中添加真实浏览器的cookies(从本地浏览器访问目标站点后复制)
4. 检查GAE代理兼容性
GAE对出站代理有特殊限制:
- 确保代理支持CONNECT方法
- 尝试切换为
socks5代理,可能兼容性更好,修改代理字典:
proxy_dict = { 'https': f'socks5://{proxy}' }
内容的提问来源于stack exchange,提问作者Bear
相关产品推荐
相关产品推荐

