爬蟲項目中遇到了一個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字段,我這里沒有添加文件上傳,文件同理