Python通过HTTP上传文件:requests库实战与关键参数解析
本文详解Python如何使用requests库通过HTTP协议上传文件。重点解析登录保持Session、利用fiddler抓包分析请求参数,以及data与files参数的配合使用。特别强调在上传文件时,headers中严禁手动指定Content-Type,需交由requests库自动生成,否则会导致上传失败。
本文主要探讨基于multipart/form-data格式的文件上传实现。目前,绝大多数HTTP协议下的文件上传操作均采用此种格式进行数据传输。
1 实现思路
通常情况下,向特定地址上传文件前需完成身份验证。首先通过登录接口获取Cookies,随后在上传文件的POST请求中携带该Cookies以维持会话状态。
为了准确构造上传请求,建议通过浏览器开发者工具或Fiddler等抓包软件,观察网站实际的文件上传行为,并据此组装POST请求。
核心原则如下:在POST请求中,使用files参数接收文件对象相关数据,同时通过data或json参数传递请求体中的其他非文件参数。
2 具体实现步骤
2.1 网站登录处理
使用requests.session()对象执行登录操作。此举旨在复用会话对象,后续直接利用该对象发送POST上传请求,无需在每次请求体中手动添加Cookies。
第一步是定位登录接口的URL地址。

第二步是提取登录请求的Headers头部信息。

第三步是确认登录所需的表单参数。

参考代码如下:
import requests
s = requests.session()
res1 = s.post(
url="http://127.0.0.1:5000/login",
headers={
'Host': '127.0.0.1:5000',
'Connection': 'keep-alive',
'Content-Length': '28',
'Cache-Control': 'max-age=0',
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"',
'sec-ch-ua-mobile': '?0',
'Upgrade-Insecure-Requests': '1',
'Origin': 'http://127.0.0.1:5000',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Sec-Fetch-Dest': 'document',
'Referer': 'http://127.0.0.1:5000/login',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9'
},
data={
"account": "admin",
"password": "admin"
}
)
2.2 手动上传文件及HTTP请求参数分析
由于Chrome浏览器开发者工具难以直接查看文件上传时的HTTP请求详细参数,此处选用Fiddler进行抓包分析。

抓包结果展示如下:

关键说明:
图中第一个红框内的参数值呈现为乱码,这实际上是上传文件的二进制数据表现。这部分数据在代码中通过files参数进行接收。
第二个红框中name对应的值为k(例如cid即为k值),其下一行的值7为v值。此类普通参数需通过data参数进行接收。
上述为HTTP请求的Raw格式,实际开发中通常参考WebForms格式的HTTP请求进行理解。
分
完成参数分析后,可参考以下代码实现:
res2 = s.post(
url="http://127.0.0.1:5000/upload",
headers={
'Host': '127.0.0.1:5000',
'Connection': 'keep-alive',
'Content-Length': '28',
'Cache-Control': 'max-age=0',
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"',
'sec-ch-ua-mobile': '?0',
'Upgrade-Insecure-Requests': '1',
'Origin': 'http://127.0.0.1:5000',
# 'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-User': '?1',
'Sec-Fetch-Dest': 'document',
'Referer': 'http://127.0.0.1:5000/login',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9'
},
files={
"filename_list": open("./test", "rb"),
"Content-Type": "text/plain",
"Content-Disposition": "form-data",
"filename": "test"
},
data={
"cid": "7"
}
)
3 三个关键注意事项
3.1 data参数处理
需仔细核对k值与抓包数据的一致性。


3.2 files参数配置
此部分至关重要,用于指定上传的文件对象。filename_list参数代表文件对象,而filename值通常对应上传后文件的名称(该字段可选)。


3.3 Content-Type参数处理
若通过form-data方式上传文件,在组装POST请求时,headers参数中绝对不能包含Content-Type字段。必须交由requests库自动添加该元素。
若手动指定Content-Type,将导致上传失败,这一点极为重要。
观察代码可知,并未显式传递Content-Type参数,但抓包结果显示该参数存在。因此,代码中严禁添加此参数。

实际抓包验证中确实包含该参数。

通过实际上传抓包验证即可,虽然与浏览器直接上传略有差异,但不影响文件上传功能。
至此,关于Python通过HTTP上传文件的介绍完毕。如需了解更多Python文件上传相关内容,建议搜索本站过往文章或继续阅读后续相关文章,感谢支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









