Python反爬JS逆向解析(七)-----某不知名网站js加密cookie反爬_execjs._exceptions.programerror: referenceerror: d-程序员宅基地

技术标签: 爬虫Web  

采集前建议:找好代理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函数调起程序:

                                            

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36853469/article/details/105022598

智能推荐

while循环&CPU占用率高问题深入分析与解决方案_main函数使用while(1)循环cpu占用99-程序员宅基地

文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。​​​​​​while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99

【无标题】jetbrains idea shift f6不生效_idea shift +f6快捷键不生效-程序员宅基地

文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效

node.js学习笔记之Node中的核心模块_node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是-程序员宅基地

文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是

数学建模【SPSS 下载-安装、方差分析与回归分析的SPSS实现(软件概述、方差分析、回归分析)】_化工数学模型数据回归软件-程序员宅基地

文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件

利用hutool实现邮件发送功能_hutool发送邮件-程序员宅基地

文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件

docker安装elasticsearch,elasticsearch-head,kibana,ik分词器_docker安装kibana连接elasticsearch并且elasticsearch有密码-程序员宅基地

文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码

随便推点

Python 攻克移动开发失败!_beeware-程序员宅基地

文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware

Swift4.0_Timer 的基本使用_swift timer 暂停-程序员宅基地

文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停

元素三大等待-程序员宅基地

文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待

Java软件工程师职位分析_java岗位分析-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析

Java:Unreachable code的解决方法_java unreachable code-程序员宅基地

文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code

标签data-*自定义属性值和根据data属性值查找对应标签_如何根据data-*属性获取对应的标签对象-程序员宅基地

文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象

推荐文章

热门文章

相关标签