Python爬虫处理奇葩的请求参数payload
引言
偶然的发现某网站,采用的是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
这种,就非常奇葩了,这也是文章开头就说了下的格式
你乍一看,它是个列表,尾部看长度大胆猜测是个时间戳,你把时间戳删掉然后用列表去请求,
1 2 3 4 5 6 7 8 9 10 11 | 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本质上就是个字符串,那么也就是说,请求参数其实可以是字符串的,列表不行,我就直接转为字符串看看
1 2 3 4 5 6 7 8 9 10 11 | 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才行,最后得出如下结果:
1 2 3 4 5 6 7 8 9 10 11 12 | 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还有没有其他的形式,后续遇到再补充
解决了就很简单,没解决就很焦灼,就会一直在想要怎么去拼凑出这种格式,其实,多想想,多查查,遇到问题自己解决,尽量别去问别人
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】