requests发送multipart/form-data请求
爬虫项目中遇到了一个POST请求,抓包显示请求头为
传输的数据为:
这种情况下直接通过data参数传入字典并不能得到正确响应,都是返回操作失败,问题就出在这个请求头上,这里我使用了https://httpbin.org/网站进行请求测试,使用了requests_toolbelt包的MultipartEncoder方法对需要传输的数据进行了处理,代码如下
import requests from requests_toolbelt import MultipartEncoder url = 'http://127.0.0.1/post' headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36", }
# 需要传输的字段 fields = { "name": (None, "test"), "age": (None, "18"), "sex": (None, "男") } m_data = MultipartEncoder(fields, boundary='----WebKitFormBoundaryBYoo1p7ErQLZBi0m') headers['Content-Type'] = m_data.content_type r = requests.post(url, headers=headers, data=m_data.to_string()) print(r.text)
得到的响应如下:
这里可以看到我们的请求头在服务端已经显示为:"multipart/form-data; boundary=----WebKitFormBoundaryBYoo1p7ErQLZBi0m" 和抓包时得到的数据一致,其次查看form参数也正确上传,这里需要注意的是如果想要查看
m_data.to_string()的值,应当使用另一个变量进行存储,而不应当像下面这样直接打印
# 部分代码。上面省略 m_data = MultipartEncoder(fields, boundary='----WebKitFormBoundaryBYoo1p7ErQLZBi0m') print("第一次:", m_data.to_string()) print("第二次:", m_data.to_string()) headers['Content-Type'] = m_data.content_type r = requests.post(url, headers=headers, data=m_data.to_string()) # 控制台打印结果如下: 第一次: b'------WebKitFormBoundaryBYoo1p7ErQLZBi0m\r\nContent-Disposition: form-data; name="name"\r\n\r\ntest\r\n------WebKitFormBoundaryBYoo1p7ErQLZBi0m\r\nContent-Disposition: form-data; name="age"\r\n\r\n18\r\n------WebKitFormBoundaryBYoo1p7ErQLZBi0m\r\nContent-Disposition: form-data; name="sex"\r\n\r\n\xe7\x94\xb7\r\n------WebKitFormBoundaryBYoo1p7ErQLZBi0m--\r\n' 第二次: b'' { "args": {}, "data": "", "files": {}, "form": {}, "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Content-Length": "0", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryBYoo1p7ErQLZBi0m", "Host": "127.0.0.1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.55 Safari/537.36" }, "json": null, "origin": "172.17.0.1", "url": "http://127.0.0.1/post" }
可以看到第二次打印的值已经为空,而服务端返回显示并没有接收到任何form字段,我这里没有添加文件上传,文件同理