python通過http上傳文件思路詳解
這裡主要是解決multipart/form-data這種格式的文件上傳,基本現在http協議上傳文件基本上都是通過這種格式上傳
1 思路
一般情況下,如果我們往一個地址上傳文件,則必須要登陸,登陸成功後,拿到cookies,然後在上傳文件的請求攜帶這個cookies。
然後我們就需要通過瀏覽器在網站上傳文件,這個時候我們需要打開瀏覽器的開發者工具或者fiddler,然後按照抓到包組裝我們的上傳文件的post請求
大傢把握一個原則就是:在post請求中,用files參數來接受文件對象相關的參數,通過data/json參數接受post請求體的其他參數即可。
2 實現
2.1 登陸網站
使用requests.session()對象登陸網站,這裡主要為瞭方便,下次直接用這個對象發送post上傳文件的請求即可,不需要我們在請求體中添加cookies
查找登錄的URL
查找請求頭
查找登錄參數
代碼如下:
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請求的參數
由於谷歌瀏覽器無法查看上傳文件時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這個參數中一定不能要包括這個值,由requests庫幫添加這個元素
如果我們自作聰明,會導致上傳失敗的,這裡非常重要!!!
大傢可以看到,我在代碼中沒有傳遞content-type這個參數,但是抓包是有這個參數的,所以這個參數我們一定不能加
實際抓包有這個參數
實際上傳抓包驗證即可,和瀏覽器上傳略有不同,但是不影響上傳
到此這篇關於python通過http上傳文件的文章就介紹到這瞭,更多相關python上傳文件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 基於Python獲取亞馬遜的評論信息的處理
- python接口自動化使用requests庫發送http請求
- python3 requests 各種發送方式詳解
- .NET 6中間件Http Logging使用介紹
- Python音樂爬蟲完美繞過反爬