Flask处理GET请求时遇'tuple'无法转为整数错误求解决
搭建Flask代理服务器转发请求到Google时遇到TypeError错误
我正在搭建一个代理服务器(术语是否正确?),目标是把Flask Web服务器收到的所有请求转发到google.com,再把结果返回给用户。比如访问127.0.0.1/search?q=stack%20overflow时,应该返回google.com/search?q=stack%20overflow的内容。
错误出在Flask而非我的代码中。
感谢@LukeWoodward指出这一点。
我的代码
from flask import Flask, request, Response import requests import urllib.parse app = Flask(__name__) # Add percent codes (like %20) to URLs def add_percent_codes(urlsection): return urllib.parse.quote(urlsection.encode('utf8')) def parse_sent_args(args_dict): args_str = '?' for key in args_dict: args_str += str(key) + '=' + str(args_dict[key]) + '&' return args_str[:-1] # Define the handling function for every packet def forward_packet(packet): # Modify or process the packet as needed print('Received packet:', packet) try: # Forward the packet to Google.com google_response = requests.get('https://www.google.com/' + packet) response_to_return = \ [google_response.content.decode('utf8', errors='ignore'), int(google_response.status_code), bytes(google_response.headers.items()).decode('utf8', errors='ignore')] print('Forwarded packet to Google.com.') # Return the response return response_to_return except requests.exceptions.HTTPError as e: print('Error forwarding packet:', e) return 'HTTPError occurred: {}'.format(e), 500 except requests.exceptions.RequestException as e: print('Error forwarding packet:', e) return 'RequestException occurred: {}'.format(e), 500 def handle_get_request(path): try: # Call the handling function for the packet response = forward_packet(path) return response finally: pass #except Exception as e: #print('Error handling GET request:\n') #return str(e), 500 @app.route('/<path:path>', methods=['GET']) def handle_get(path): # Get the incoming packet from the URL path args_dict = dict(request.args) end_url_args = parse_sent_args(args_dict) full_path = '/' + path + end_url_args return handle_get_request(path) if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
错误信息
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/flask/app.py", line 2525, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/flask/app.py", line 1822, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/flask/app.py", line 1820, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/lib/python3/dist-packages/flask/app.py", line 1796, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/eesa/Code/proxyforblocking/attempt2.py", line 63, in handle_get return handle_get_request(path) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/eesa/Code/proxyforblocking/attempt2.py", line 49, in handle_get_request response = forward_packet(path) ^^^^^^^^^^^^^^^^^^^^ File "/home/eesa/Code/proxyforblocking/attempt2.py", line 30, in forward_packet bytes(google_response.headers.items()).decode('utf8', errors='ignore')] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: 'tuple' object cannot be interpreted as an integer
小提示:我注释掉了错误处理以获取完整的回溯信息,并添加了finally块以避免其他错误。
解决方案
1. 错误根源
报错的核心是bytes(google_response.headers.items())这行代码:headers.items()返回的是由(键, 值)元组组成的迭代器,直接传给bytes()会触发TypeError——因为bytes()只接受整数、整数序列或字符串作为参数,无法直接处理元组迭代器。
另外代码还有两个隐性问题:
handle_get函数拼接了带参数的full_path,但并未传给handle_get_request,导致转发到Google的请求丢失URL参数- 返回给Flask的响应格式不符合规范,手动处理响应头的方式错误
2. 修正后的代码
from flask import Flask, request, Response import requests app = Flask(__name__) @app.route('/<path:path>', methods=['GET']) def handle_get(path): # 拼接完整的目标URL,包含原请求的所有参数 full_url = f'https://www.google.com/{path}' if request.args: full_url += '?' + request.query_string.decode('utf-8') try: # 转发请求到Google,过滤原请求的Host头避免被拒绝 google_response = requests.get( full_url, headers={k: v for k, v in request.headers if k.lower() != 'host'}, allow_redirects=False ) # 用Flask的Response对象构造合法响应,直接复用Google的状态码、头和内容 response = Response( google_response.content, status=google_response.status_code, headers=dict(google_response.headers) ) return response except requests.exceptions.HTTPError as e: return f'HTTPError occurred: {e}', 500 except requests.exceptions.RequestException as e: return f'RequestException occurred: {e}', 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
3. 关键修正点
- 用
request.query_string直接获取已编码的参数,避免手动拼接时的编码错误 - 用Flask原生
Response对象构造返回结果,正确传递响应状态码和头信息,无需手动解码内容 - 转发请求时过滤掉
Host头,防止Google拒绝非官方Host的请求 - 移除冗余的辅助函数,简化逻辑结构
- 确保转发的URL包含完整路径和参数,解决原代码中参数丢失的问题
内容的提问来源于stack exchange,提问作者imeesa
相关产品推荐
相关产品推荐

