Python 2.7使用requests发送带数据xlsx到Telegram报错求助
问题:Python 2.7下requests发送含数据的xlsx文件到Telegram报错
我用Python 2.7编写软件,通过requests库的HTTPS请求向Telegram聊天发送.xlsx文件。发送仅含列标题的空文件时无报错,但发送包含实际数据的文件时,出现如下错误:
Traceback (most recent call last): File "<module:project.TelegramBot>", line 68, in SendDocument File "C:\Users\SimoneMaffei\.ignition\cache\gwlocalhost_8088\C0\pylib\requests\api.py", line 109, in post return request('post', url, data=data, json=json, **kwargs) File "C:\Users\SimoneMaffei\.ignition\cache\gwlocalhost_8088\C0\pylib\requests\api.py", line 50, in request response = session.request(method=method, url=url, **kwargs) File "C:\Users\SimoneMaffei\.ignition\cache\gwlocalhost_8088\C0\pylib\requests\sessions.py", line 465, in request resp = self.send(prep, **send_kwargs) File "C:\Users\SimoneMaffei\.ignition\cache\gwlocalhost_8088\C0\pylib\requests\sessions.py", line 573, in send r = adapter.send(request, **kwargs) File "C:\Users\SimoneMaffei\.ignition\cache\gwlocalhost_8088\C0\pylib\requests\adapters.py", line 415, in send raise ConnectionError(err, request=request) ConnectionError: ('Connection aborted.', BadStatusLine("''",))
我的代码如下:
import traceback import json import requests apiToken = "12345" chatID = "12345" def SendDocument(): result = {'isValid': False, 'result': None} try: params = {} params['chat_id'] = chatID params['document'] = 'attach://file' files = {'file': open("C:\\Users\\SimoneMaffei\\Desktop\\report.xlsx", "rb")} finalURL = "https://api.telegram.org/bot" + apiToken + "/sendDocument" httpResult = requests.post(finalURL, data = params, files=files) result["isValid"] = True result["result"] = httpResult except: print(traceback.format_exc()) return result print(SendDocument())
Python 3.x环境下无此问题,但我无法切换至该版本,希望知道问题原因。
问题原因
这个问题根源在于Python 2.7适配的旧版requests库对多部分表单数据(multipart/form-data)的处理缺陷:
- Python 2.7能用的requests最高版本是2.27.1,旧版本(尤其是早于2.20的版本)在构造大文件的multipart请求时,存在编码逻辑漏洞,导致请求格式不符合HTTP规范。
- 空文件体积小,请求数据包完整,Telegram服务器能正常解析;但带数据的文件体积增大后,错误的multipart编码会让服务器无法识别请求,直接断开连接,返回空状态行(BadStatusLine("''"))。
- Python 3.x的requests库后续版本修复了这类multipart请求的编码问题,因此不会出现该报错。
可选解决办法(无需切换Python版本)
- 升级到Python 2.7可用的最新requests版本:
pip install requests==2.27.1 - 用requests-toolbelt库替代原生files参数构造请求:
先安装适配Py2的版本:
修改后的代码:pip install requests-toolbelt==0.10.1import traceback import requests from requests_toolbelt import MultipartEncoder apiToken = "12345" chatID = "12345" def SendDocument(): result = {'isValid': False, 'result': None} try: # 手动构造multipart表单,指定文件MIME类型 m = MultipartEncoder( fields={ 'chat_id': chatID, 'file': ('report.xlsx', open("C:\\Users\\SimoneMaffei\\Desktop\\report.xlsx", "rb"), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') } ) finalURL = "https://api.telegram.org/bot" + apiToken + "/sendDocument" # 传入构造好的表单和对应的Content-Type httpResult = requests.post(finalURL, data=m, headers={'Content-Type': m.content_type}) result["isValid"] = True result["result"] = httpResult except: print(traceback.format_exc()) return result print(SendDocument())
内容的提问来源于stack exchange,提问作者Simone Maffei
相关产品推荐
相关产品推荐

