引言
偶然的發現某網站,采用的是post請求,然后打開f12調試查看:
它提交的參數並不是我們熟悉的formdata類型,而是payload,這種是怎么回事呢,先了解下什么是payload
Request Payload
我們都知道,前端與后端交互,一般有幾種模式,且通過字段Content-Type區分
Content-Type:
- application/x-www-form-urlencoded
- application/json
- multipart/form-data
寫過后端接口的朋友對這個應該不陌生
寫過前端的朋友,看這個,你應該也不陌生
<form action="http://www.example.com" method="POST" enctype="application/x-www-form-urlencoded">
application/x-www-form-urlencoded
這就是默認的模式,也就是我們平時寫的請求參數是字典格式,然后在發送請求時會把字典的鍵值轉為key1=value1&key2=value2...等等的
application/json
這個看名字就知道,就是json格式,也就是我們遇到的那種ajax異步請求的,帶的參數就是字典的樣子,只是被轉成了字符串
multipart/form-data
這種很少見,它也是上傳文件需要用的模式,這個前端的朋友應該更了解一點,如果傳遞的不是文件的話,這種模式就是本篇文章要說的Request Payload類型
Payload有哪些形式提現
第一種
這種我見過的最多的就是下面這種:
{"token":"","pn":20,"rn":10,"sdt":"","edt":"","wd":"","inc_wd":"","exc_wd":"","fields":"title","cnum":"001;002;003;004;005;006;007;008;009;010","sort":"{\"showdate\":\"0\"}","ssort":"title","cl":200,"terminal":"","condition":[{"fieldName":"categorynum","isLike":true,"likeType":2,"equal":"001001"}],"time":null,"highlights":"title","statistics":null,"unionCondition":null,"accuracy":"100","noParticiple":"0","searchRange":null,"isBusiness":1}
這個你別看着簡單,注意里面有兩個參數,null,false,true,當你用json提交的話,是無法正常返回值的,因為什么,Python里,沒有null和false的關鍵詞,只有None和False,這個我暫且對這種命名為編程語言語法隔離(我自己取的啊,很隨意)
這種怎么辦,把null改為None,false改為False,true改為True,然后在發送請求的時候把參數用json.dumps()一下轉為字符串,在提交請求的時候,None會自動變成null,False和True也相同,這樣就和所需請求格式符合,就可以正常返回值
第二種
url是https://xxxx/TrueLoreAjax/TrueLore.Web.WebUI.AjaxHelper,TrueLore.Web.WebUI.ashx
["TrueLore.Web.WebUI.WebAjaxService","GetPageXMXX",[45,15,1,130,false,"XXBT","","FBQSSJ DESC"],null,null]1584152836329
這種,就非常奇葩了,這也是文章開頭就說了下的格式
你乍一看,它是個列表,尾部看長度大膽猜測是個時間戳,你把時間戳刪掉然后用列表去請求,
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3738.0 Safari/537.36 Edg/75.0.107.0'
}
url = '' #保密
data = ["TrueLore.Web.WebUI.WebAjaxService","GetPageXMXX",[45,15,1,130,false,"XXBT","","FBQSSJ DESC"]
req = requests.post(url, headers=headers, data=data, verify=False)
res = req.content.decode('utf-8')
print(res)
一運行,當場懵逼,我第一次遇到這個的時候也是這樣,我還沒運行我就抱着忐忑的心態,因為我就預感不行,參數怎么能是列表形式呢,運行的結果肯定是不行的,得不到結果
怎么辦呢?
我想了下,在遇到最多的ajax時都可以是json字符串,json本質上就是個字符串,那么也就是說,請求參數其實可以是字符串的,列表不行,我就直接轉為字符串看看
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3738.0 Safari/537.36 Edg/75.0.107.0'
}
url ='' # 保密
data = ["TrueLore.Web.WebUI.WebAjaxService","GetPageXMXX",[45,15,1,130,false,"XXBT","","FBQSSJ DESC"],null,null]
req = requests.post(url, headers=headers, data=str(data), verify=False)
res = req.content.decode('utf-8')
print(res)
運行發現還是不行,事后我才發現,其實我已經離成功很近了,我又去研究這種到底是咋回事,全網搜有關TrueLore的資料,已經url是TrueLore.Web.WebUI.AjaxHelper,TrueLore.Web.WebUI.ashx相關的東西,找了半天,有了大概的了解后,我突然想起,我的請求頭好像只有個UA,我把瀏覽器上的請求頭全部帶上看看,
發現他媽的居然就可以了,最后根據篩選發現,請求頭必須得有Ajax-method': 'AjaxMethodFactory才行,最后得出如下結果:
headers = {
'Ajax-method': 'AjaxMethodFactory', # 這個很重要
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3738.0 Safari/537.36 Edg/75.0.107.0'
}
url = 'https://xxxxxx/TrueLoreAjax/TrueLore.Web.WebUI.AjaxHelper,TrueLore.Web.WebUI.ashx'
data = '["TrueLore.Web.WebUI.WebAjaxService","GetPageXMXX",[45,15,1,130,false,"XXBT","","FBQSSJ DESC"],null,null]'
req = requests.post(url, headers=headers, data=data, verify=False)
res = req.content.decode('utf-8')
print(res)
運行結果:
成功,ojbk
2020-3-20更新
如上,返回的結果格式很奇怪,外層是一個列表,內層里的數據,類似字典,eval一下看看,如下:
沒辦法,所有的key都沒有帶上引號,並不被識別為字符串,而是被當變量處理
怎么辦? 用正則表達式的替換
還是報錯了,但是格式有了,發現報錯原因是如下,時間格式不對
做如下處理即可:
代碼:
null = None true = True false = False headers = { 'Ajax-method': 'AjaxMethodFactory', 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3738.0 Safari/537.36 Edg/75.0.107.0' } url = 'http://xxxx.com/TrueLoreAjax/TrueLore.Web.WebUI.AjaxHelper,TrueLore.Web.WebUI.ashx' data = '["TrueLore.Web.WebUI.WebAjaxService","GetPageJYXXFB_JSGC",[15,15,2,270,"","",-1,-1,"-1",-1,"-1","XMBH","","XXKSSJ DESC"],null,null]' req = requests.post(url, headers=headers, data=data, verify=False) res = req.content.decode('utf-8') res = re.sub(r'(\w*?):', r'"\1":', res) res = re.sub(r'"(\d{2})":"(\d{2})":(\d{2}\.\d{3})"', r'\1:\2:\3"', res) res = re.sub(r'"(\d{2})":"(\d{2})":(\d{2})"', r'\1:\2:\3"', res) data = eval(res) print(res)
如果還不行,那么就找到報錯的字段,針對處理即可
payload還有沒有其他的形式,后續遇到再補充
解決了就很簡單,沒解決就很焦灼,就會一直在想要怎么去拼湊出這種格式,其實,多想想,多查查,遇到問題自己解決,盡量別去問別人