Python反爬JS逆向解析(七)-----某不知名网站js加密cookie反爬

采集前建议:找好代理IP,别对该网站发起攻击性访问,否则爬虫用的好,监狱进的早

1.网站:

点此直达该不知名网站

                                                                         

2.正常请求网站:

拿到网址,查看完基本的信息后,应该就是用代码对网站发起请求了。

# -*- coding: UTF-8 -*-
'''
@Author :Jason
没有代理的自己找个代理,没的话也可去掉代理
'''
import requests,random
from pprint import pprint
proxies = random.choice([
    {"HTTPS":""}
    ])

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
}

res = requests.get(url= "https://www.mps.gov.cn/n2253534/n2253535/index.html",proxies=proxies,headers = headers)
pprint(res.text)

打印内容:

<script>var x="1500@join@match@0xEDB88320@@@Expires@@attachEvent@Mar@@document@@cSELK@charAt@Array@reverse@firstChild@4@onreadystatechange@@nQ@for@0xFF@@addEventListener@@createElement@a@false@replace@@@24@08@@@6@@0@20@1584861863@@@challenge@b@p@search@8@@setTimeout@@cookie@3@catch@f@div@@@36@d@return@toLowerCase@@@2@href@var@fromCharCode@e@@Sun@22@33@@@String@try@window@pathname@@captcha@JgSe0upZ@Path@@@charCodeAt@new@DOMContentLoaded@parseInt@@@RegExp@@@GMT@https@@@eval@split@innerHTML@@if@function@BDjajy@g@@substr@while@23@length@toString@@@rOm9XFMtA3QKV7nYsPGT4lifyWwkq5vcjH2IdxUoCbhERLaz81DNB6@@@@@0v@@__jsl_clearance@1@else@chars@@location".replace(/@*$/,"").split("@"),y="2e 1g=3o(){1o('4k.2d=4k.2q+4k.1l.14(/[\\?|&]31-1i/,\\'\\')',1);c.1q='4f=1f.2k|1d|'+(3o(){2e 46=[3o(1g){28 1g},3o(46){28 46},(3o(){2e 1g=c.11('23');1g.3l='<12 2d=\\'/\\'>3m</12>';1g=1g.i.2d;2e 46=1g.3(/3g?:\\/\\//)[1d];1g=1g.41(46.44).29();28 3o(46){n(2e 3m=1d;3m<46.44;3m++){46[3m]=1g.f(46[3m])};28 46.2('')}})(),3o(1g){28 3j('2n.2f('+1g+')')}],3m=['1k',[(((+!-{})|(-~[]<<-~[]))+[]+[])+[(-~[]+[j]>>-~[])]],(2c+[]+[]),[[(-~[]+[j]>>-~[])]+((+![])+[]+[[]][1d])],'m',[[(+!-{})]+(2c+[]+[])],'e',[![]+[]+[[]][1d]][1d].f((-~[]<<-~[])),'1j',(2c+[]+[]),'3p',[(-~((-~[]+[-~(+!-{})]>>-~(+!-{})))+(-~[]<<-~[])+((-~[]<<-~[])^(+!-{}))+[[]][1d])],'4d',[[(+!-{})]+(2c+[]+[])+((+![])+[]+[[]][1d])],(-~((-~[]+[-~(+!-{})]>>-~(+!-{})))+[]),[(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+j+[])+[2c+(2c^(+!-{}))]],[(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+j+[])],[(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+j+[])+[2c+(2c^(+!-{}))],(((+!-{})|(-~[]<<-~[]))+[]+[])+[(-~[]+[j]>>-~[])]],(((+!-{})|(-~[]<<-~[]))+[]+[]),[[1b]+(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+j+[])]];n(2e 1g=1d;1g<3m.44;1g++){3m[1g]=46[[4g,20,1d,20,4g,2c,4g,1d,4g,1d,4g,2c,4g,20,1d,20,2c,20,1d,20][1g]](3m[1g])};28 3m.2('')})()+';7=2i, 2j-a-1e 18:17:43 3f;33=/;'};3n((3o(){2o{28 !!2p.q;}21(2g){28 13;}})()){c.q('38',1g,13)}4h{c.9('k',1g)}",f=function(x,y){var a=0,b=0,c=0;x=x.split("");y=y||99;while((a=x.shift())&&(b=a.charCodeAt(0)-77.5))c=(Math.abs(b)<13?(b+48.5):parseInt(a,36))+y*c;return c},z=f(y.match(/\w/g).sort(function(x,y){return f(x)-f(y)}).pop());while(z++)try{eval(y.replace(/\b\w+\b/g, function(y){return x[f(y,z)-1]||("_"+y)}));break}catch(_){}</script>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             

这样看费眼费脑,我们需要将JS代码格式化(美化):

<script>
	var x = "@join@window@g@@e@chars@Mar@charCodeAt@eval@@toString@@@@search@String@@fromCharCode@@var@8@onreadystatechange@@function@@reverse@4@new@replace@Thu@@@@substr@19@GMT@attachEvent@@false@length@__jsl_clearance@@@08@@0xEDB88320@@0xFF@match@@parseInt@cookie@DOMContentLoaded@for@firstChild@1@0@setTimeout@6@captcha@RegExp@f@@@div@document@@charAt@location@pathname@@return@https@d@@@else@href@Expires@@try@rOm9XFMtA3QKV7nYsPGT4lifyWwkq5vcjH2IdxUoCbhERLaz81DNB6@@while@2@innerHTML@@@@@catch@@36@099@Path@@@@@20@toLowerCase@@55@@@@@createElement@split@challenge@@@if@52@addEventListener@@Array@@a@JgSe0upZ@@@1584604552@1500@@@".replace(/@*$/, "").split("@"),
	y = "l M=p(){15('1g.1p=1g.1h+1g.g.u(/[\\?|&]17-23/,\\'\\')',2h);1d.R='G=2g.1F|14|'+(p(){l 1K=[p(M){1j a('h.j('+M+')')},p(M){11(l 1K=14;1K<M.F;1K++){M[1K]=Q(M[1K]).c(1E)};1j M.2('')}],M=[[[(+!-{})]+[16],(1w+[]+[])+[16],(1w+[]+[])+[1w+(1w^(+!-{}))],[(+!-{})]+(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[]),[(+!-{})]+((+![])+[]+[[]][14]),[(+!-{})]+(((+!-{})|(-~[]<<-~[]))+[]+[])],[(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[])+(-~((-~[]+[-~(+!-{})]>>-~(+!-{})))+(-~[]<<-~[])+((-~[]<<-~[])^(+!-{}))+[[]][14]),[1w+(1w^(+!-{}))]+(-~((-~[]+[-~(+!-{})]>>-~(+!-{})))+[])],[(1w+[]+[])+[(+!-{})],[(+!-{})]+(-~((-~[]+[-~(+!-{})]>>-~(+!-{})))+[]),[(+!-{})]+[16]],[[1w+(1w^(+!-{}))]+(((+!-{})|(-~[]<<-~[]))+[]+[]),[16]+[1w+(1w^(+!-{}))],(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[])+[(-~[]+[s]>>-~[])]],[(((+!-{})|(-~[]<<-~[]))+[]+[])+((+![])+[]+[[]][14])],[[(-~[]+[s]>>-~[])]+[1w+(1w^(+!-{}))],(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[])+(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[])],[[(+!-{})]+[16]],[[(-~[]+[s]>>-~[])]+((+![])+[]+[[]][14]),[(-~[]+[s]>>-~[])]+[(+!-{})],[1w+(1w^(+!-{}))]+(((+!-{})|(-~[]<<-~[]))+[]+[]),[1w+(1w^(+!-{}))]+[1w+(1w^(+!-{}))],[(-~[]+[s]>>-~[])]+(((+!-{})|(-~[]<<-~[]))+[]+[]),[(-~[]+[s]>>-~[])]+(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[])],[[(+!-{})]+(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[]),(1w+[]+[])+[16]],[[16]+[1w+(1w^(+!-{}))],(((+!-{})|(-~[]<<-~[]))+[]+[])+[(-~[]+[s]>>-~[])],[1w+(1w^(+!-{}))]+[(+!-{})],[16]+(-~[]+(-~[]+[-~(+!-{})]>>-~(+!-{}))+s+[])]];11(l 1I=14;1I<M.F;1I++){M[1I]=1K.r()[((+![])+[]+[[]][14])](M[1I])};1j M.2('')})()+';1q=v, A-8-1L J:1O:27 B;1G=/;'};26((p(){1s{1j !!3.28;}1C(6){1j E;}})()){1d.28('10',M,E)}1o{1d.C('n',M)}",
	f = function(x, y) {
		var a = 0,
		b = 0,
		c = 0;
		x = x.split("");
		y = y || 99;
		while ((a = x.shift()) && (b = a.charCodeAt(0) - 77.5)) c = (Math.abs(b) < 13 ? (b + 48.5) : parseInt(a, 36)) + y * c;
		return c
	},
	z = f(y.match(/\w/g).sort(function(x, y) {
		return f(x) - f(y)
	}).pop());
	while (z++) try {
		eval(y.replace(/\b\w+\b/g,
		function(y) {
			return x[f(y, z) - 1] || ("_" + y)
		}));
		break
	} catch(_) {}
</script>

<script></script>标签,很明显返回的内容只是一段JS代码,并不是我们需要的数据,先大略搂一眼这茬JS就行了。

3.分析:

再次对网站发起请求,Fiddler抓包

其中#1就是我们获取到的JS代码(如下图),但是状态码有点奇怪哈,521,我们都知道状态码5XX表示的是内部服务器(HTTP-Internal Server Error)错误说明IIS服务器无法解析ASP代码,也就是说这是服务器本身的错误,而不是我们的请求错误,继续。。。

#2,#4的话没看出啥作用来(其实是我这个渣渣没看出啥作用来,懂得可以评论帮我解释下)

#3的话就是我们需要的数据了

       图略,自行查看,太优秀导致无法过审。

到此,#1,#2,#3,#4基本就是从发起请求到请求结束(获取到我们需要的数据)

                                    

看完后好像并没有什么发现?

对比一下#1和#3两个请求,我们发现请求只是请求时请求头稍微不同,设置并增加了一个cookie

          

                      

随便点击新闻页面的一个新闻,观察Fiddler的抓包情况,发现已经可以正常获得页面了,而新闻页面和#3的cookie是一样的。很明显了,网站进行了cookie验证,脚本带上cookie发起请求,是可以直接将数据请求过来的。

如果你只是需要采集一遍数据的话,那么直接将JS、复制过来也是可以用的,但是,作为长久之计,我们还是需要搞懂cookie的来龙去脉。

4.解析

先分析cookie值

设置:Set-Cookie: __jsluid_s=669f5e06a3b3f2fd2679ef2f4ca91ce6; max-age=31536000; path=/; HttpOnly; secure


最后需要的:Cookie: __jsluid_s=669f5e06a3b3f2fd2679ef2f4ca91ce6; __jsl_clearance=1584607180.68|0|b9aYrP21LoBfBNdYNlcLmJlEhbI%3D

 #1状态码521时设置了cookie(Set-Cookie),再次发起请求时Cookie又有点不一样了,多了一个__jsl_clearance。其中__jsluid_s在发起请求时我们可以轻松拿到,__jsl_clearance=1584607180.68|0|b9aYrP21LoBfBNdYNlcLmJlEhbI%3D,其中第一截凭感觉像是时间戳(虽然它就是,但是我们还是需要验证的,毕竟时间戳上还是有很多手脚可以做的),第二截0,第三截看不出来,但是从%3D我们大致可以知道,这难道是经过URL编码?没法,我们到回之前对之前获取到的JS代码进行处理吧!!!

JS代码美化,eval=>console.log(),在控制台输入加打印

JS代码美化,细分析,查看参数和函数等,其中看到了我们需要的__jsl_clearance参数

var _M = function() {
	setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')', 1500);
	document.cookie = '__jsl_clearance=1584606567.057|0|' + (function() {
		var _1K = [function(_M) {
			return eval('String.fromCharCode(' + _M + ')')
		},
		function(_M) {
			for (var _1K = 0; _1K < _M.length; _1K++) {
				_M[_1K] = parseInt(_M[_1K]).toString(36)
			};
			return _M.join('')
		}],
		_M = [[[2 + (2 ^ ( + !-{}))] + [( + !-{})]], [[( + !-{})] + ( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []), [( + !-{})] + ((( + !-{}) | ( - ~ [] << -~ [])) + [] + [])], [( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []) + (2 + [] + [])], [(2 + [] + []) + [2 + (2 ^ ( + !-{}))]], [( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []) + [2 + (2 ^ ( + !-{}))]], [[( + !-{})] + [( - ~ [] + [4] >> -~ [])]], [[2 + (2 ^ ( + !-{}))] + (2 + [] + [])], [[( + !-{})] + [( + !-{})]], [[( - ~ [] + [4] >> -~ [])] + ( - ~ (( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{}))) + [])], [((( + !-{}) | ( - ~ [] << -~ [])) + [] + []) + ((( + !-{}) | ( - ~ [] << -~ [])) + [] + [])], [((( + !-{}) | ( - ~ [] << -~ [])) + [] + []) + [( - ~ [] + [4] >> -~ [])], [2 + (2 ^ ( + !-{}))] + (( + ![]) + [] + [[]][0]), [6] + [6]], [[( + !-{})] + ( - ~ (( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{}))) + ( - ~ [] << -~ []) + (( - ~ [] << -~ []) ^ ( + !-{})) + [[]][0])], [[( - ~ [] + [4] >> -~ [])] + [2 + (2 ^ ( + !-{}))], [( - ~ [] + [4] >> -~ [])] + (2 + [] + [])], [(2 + [] + []) + [( - ~ [] + [4] >> -~ [])]], [[2 + (2 ^ ( + !-{}))] + [( - ~ [] + [4] >> -~ [])]], [((( + !-{}) | ( - ~ [] << -~ [])) + [] + []) + [( + !-{})]], [( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []) + (2 + [] + []), ( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []) + ( - ~ (( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{}))) + ( - ~ [] << -~ []) + (( - ~ [] << -~ []) ^ ( + !-{})) + [[]][0]), [( - ~ [] + [4] >> -~ [])] + [6], ( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []) + ( - ~ (( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{}))) + [])], [((( + !-{}) | ( - ~ [] << -~ [])) + [] + []) + ((( + !-{}) | ( - ~ [] << -~ [])) + [] + []), [( + !-{})] + ( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + [])], [[( - ~ [] + [4] >> -~ [])] + ( - ~ (( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{}))) + ( - ~ [] << -~ []) + (( - ~ [] << -~ []) ^ ( + !-{})) + [[]][0]), ( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + []) + (2 + [] + []), [( - ~ [] + [4] >> -~ [])] + ((( + !-{}) | ( - ~ [] << -~ [])) + [] + []), ((( + !-{}) | ( - ~ [] << -~ [])) + [] + []) + [( - ~ [] + [4] >> -~ [])], [2 + (2 ^ ( + !-{}))] + [( + !-{})], [6] + ( - ~ [] + ( - ~ [] + [ - ~ ( + !-{})] >> -~ ( + !-{})) + 4 + [])]];
		for (var _1I = 0; _1I < _M.length; _1I++) {
			_M[_1I] = _1K.reverse()[[( + !-{})]](_M[_1I])
		};
		return _M.join('')
	})() + ';Expires=Thu, 19-Mar-20 09:29:27 GMT;Path=/;'
};
if ((function() {
	try {
		return !! window.addEventListener;
	} catch(e) {
		return false;
	}
})()) {
	document.addEventListener('DOMContentLoaded', _M, false)
} else {
	document.attachEvent('onreadystatechange', _M)
}

 再次控制台打印,结果:

 

是的,我们需要的cookie值已经拿到了,最后,我们只需要通过代码实现就可以了。

5.填坑:

步步为营,其中遇到很多坑,一个一个详细介绍解决方法:

坑一:

execjs._exceptions.ProgramError: ReferenceError: document is not defined

具体解决方法参考博客:Python 解决execjs._exceptions.ProgramError: ReferenceError: document is not defined报错问题

坑二:

execjs._exceptions.ProgramError: ReferenceError: window is not defined

错误类型:window对象未定义

解决方法一: 定义对象:

var window = {};

解决方法二:替换

  replace("window", "'Chrome'")

以上两个方法都行,继续

坑三:前后两次访问的User-Agent一定要相同,不然还是不行(深有体会系列)

6.Python代码实现: 

填完坑,清完雷,继续玩下走,就是代码了,部分代码如下:

 获取cookie

 携带cookie访问:

最后main函数调起程序:

                                            

 声明:文章仅源自个人兴趣爱好,不涉及他用,侵权联系删。

发布了131 篇原创文章 · 获赞 172 · 访问量 64万+

猜你喜欢

转载自blog.csdn.net/qq_36853469/article/details/105022598