1. 程式人生 > >python實現post請求

python實現post請求

pyload={"token": "2280d841c47074107bb903169cd78d4d0a1345970ec6380d0909efc7e77a25cb","sign":"700eae16811bd1844e21c31c3ed0f5b0","page":"3","order":"0","limit":"12","map":""}

headers={'Host': 'usedcar.auto.sina.com.cn',
'Connection': 'keep-alive',
'Content-Length': '186',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Origin': 'http://usedcar.auto.sina.com.cn',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.0.1471.813 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://usedcar.auto.sina.com.cn/buycar/s/%E8%AF%B7%E8%BE%93%E5%85%A5%E5%93%81%E7%89%8C%E6%88%96%E8%BD%A6%E5%9E%8B',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.8',
}

d=requests.post(url,data=payload,headers=headers)

print(d)

然後伺服器報錯,但是一樣的資料在filder裡面卻是對的,這是什麼原因呢?

後來通過requests的官方文件發現,有這麼一句話:

很多時候你想要傳送的資料並非編碼為表單形式的。如果你傳遞一個 string 而不是一個 dict,那麼資料會被直接釋出出去。

通過抓包軟體fillder去看看我在pycharm裡面請求和在fillder裡面請求的東西來看,最後返回來的資料的形式完全就是不一樣了,所以對應正確的格式,我把其轉換為string,得出結果和正確一樣的,

可以正確返回的表單的值是這樣子的:

{"token":"2280d841c47074107bb903169cd78d4d0a1345970ec6380d0909efc7e77a25cb","sign":"700eae16811bd1844e21c31c3ed0f5b0","page":"3","order":"0","limit":"12","map":""}

然後我的目的就是把那些引數化為輸出為上面的資料那樣子。

所以最後形式為以下那樣子:

payload = '{"token":'+' "2280d841c47074107bb903169cd78d4d0a1345970ec6380d0909efc7e77a25cb"'+',"sign":'+'"700eae16811bd1844e21c31c3ed0f5b0"'+',"page":'+'"3"'+',"order":'+'"0"'+',"limit":'+'"12"'+',"map":'+'""'+'}'

接下來發現又是一個很尷尬的事情,伺服器直接報錯,504錯誤,開始還去找這是什麼原因,後來在網上看到是這樣子說的:

wireshark抓包發現:

用reqeusts和curl傳送的資料都是一樣的,但是,curl有帶一個header:"Content-Type": "application/x-www-form-urlencoded"

看來requests也需要加上這個頭:

headers = {"Content-Type": "application/x-www-form-urlencoded"}

最後我把我內容的headers換成以上headers,結果還真的是成功了。

雖然為什麼是那個頭,我還真的不知道是什麼一個的原因 。後續知道會陸續去更新的。

馬上看完文件發現一個問題,就馬上來記下來,在新的版本的requests裡面,除了對dict格式去編碼以外,還可以使用json格式直接去傳遞,然後它就會被自動編碼。這是 2.4.2 版的新加功能:

d=requests.post(url,json=data,headers=headers)
print d
print d.text