本文章中所有内容仅供学习交流使用,不用于其他任何目的,敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!
本文章未经许可禁止转载,禁止任何修改后二次传播,擅自使用本文讲解的技术而导致的任何意外,作者均不负责,若有侵权,请联系作者立即删除
正常的加速乐的特点是访问网站一般有三次请求:
第一次请求网站,网站返回的响应状态码为 521,响应返回 混淆的 JS 代码; 第二次请求网站,网站同样返回的响应状态码为 521,响应返回的为经过 OB 混淆的 JS 代码; 第三次请求网站,网站返回的响应状态码 200,即可正常访问到网页内容。
逆向思路:根据我们上面讲的加速乐的特点,我们想要获取到真实的 HTML 页面,需要经过以下三个步骤:
第一次请求网站,服务器返回的 Set-Cookie 中携带 jsluid_s 参数,将获取到的响应内容解密拿到第一次 jsl_clearance_s 参数的值; 携带第一次请求网站获取到的 Cookie 值再次访问网站,将获取到的响应内容解混淆逆向拿到第二次 jsl_clearance_s 参数的值; 使用携带 jsluid_s 和 jsl_clearance_s 参数的 Cookie 再次访问网站,获取到真实的 HTML 页面内容,继而采集数据。
url : aHR0cHM6Ly93d3cucHl0aG9uLXNwaWRlci5jb20vY2hhbGxlbmdlLzEx -------------这个却有些不同,应该是改写
-
第一步:首先 进入 浏览器的开发者工具,在 Network 找到 对应的请求,在Response中查看返回的内容,发现内容就在11请求链接里,这里注意(你请求后会发现携带请求都正确的情况下,请求的数据跟页面上响应的不一样)
-
第二步:使用fiddler抓包工具,看一下流程,发现其实是请求了两次,下图中请求了两次11的链接,这两个链接的区别在于cookie携带的参数不一样,第二次请求中多了一个__jsl_clearance参数。经过推敲发现这个参数应该是在第一次请求11链接后得到的。
-
第三步:直接请求第一次的11链接,携带着第一次看到的cookie,直接请求页面,我们会看到响应中有一个script的标签。
-
第三步:把中间的内容放到js文件里,格式化一下js代码,我们来看一下它的结果。
-
第四步:把 eval 的函数打印,复制出来分析,可以看到 有个document.cookie的地方,就是赋值 cookie的地方,我们直接用 Nodejs 运行 运行这段JS ,( win10 直接下载,下一步下一步安装就好了 )
这里我们需要注意三点:
1. var document 与 function createElement是我自己后来补的环境。
2. 下方代码有两处注释的地方,setTimeout与 if ((function() 注释一下是因为其实也没有什么用处。
3. _N函数调用 与 console.log(document.cookie),也是我后来自己加的
var document = {
'createElement': createElement,
};
function createElement(a) {
return {
'firstChild': {'href': 'http://www.python-spider.com/challenge/11'}
}
}
var _N = function() {
// setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')', 1500);
document.cookie = '__jsl_clearance=1681177714.791|0|' + (function() {
var _t = [function(_N) {
return _N
},
function(_t) {
return _t
},
(function() {
var _N = document.createElement('div');
_N.innerHTML = '<a href=\'/\'>_1H</a>';
_N = _N.firstChild.href;
var _t = _N.match(/https?:\/\//)[0];
_N = _N.substr(_t.length).toLowerCase();
return function(_t) {
for (var _1H = 0; _1H < _t.length; _1H++) {
_t[_1H] = _N.charAt(_t[_1H])
};
return _t.join('')
}
})(),
function(_N) {
for (var _t = 0; _t < _N.length; _t++) {
_N[_t] = parseInt(_N[_t]).toString(36)
};
return _N.join('')
}],
_N = ['clD', [( - ~~~ {} << -~~~ {}) + ( - ~~~ {} << -~~~ {})], 'V', [( - ~ [] + [] + [[]][0]) + [ - ~ - ~ {}]], 'fq', [( - ~ [] + [] + [[]][0]) + [ - ~ [] - ~ [] - ~ ! /!/ + ( - ~ [] - ~ []) * [ - ~ [] - ~ []]], ( - ~ [] + [] + [[]][0]) + ( - ~ [ - ~ - ~ {}] + [[]][0]), ( - ~ [] + [] + [[]][0]) + [( + !![[][[]]][1])]], 'LBWywKW', [(2 - ~ [ - ~ - ~ {}] + [] + [[]][0])], '%2FZyf', [( - ~ [] + [] + [[]][0]) + ( - ~ [ - ~ - ~ {}] + [[]][0])], '6', [( - ~ [] + [] + [[]][0]) + ( - ~ [ - ~ - ~ {}] + [[]][0])], '_5ffcba442c5fde8c35686219ebab7b37', ( - ~ [ - ~ - ~ {}] + [[]][0]), 'D'];
for (var _1H = 0; _1H < _N.length; _1H++) {
_N[_1H] = _t[[1, 0, 1, 2, 1, 3, 1, 2, 1, 2, 1, 3, 1, 0, 1][_1H]](_N[_1H])
};
return _N.join('')
})() + ';Expires=Tue, 12-Dec-30 09:50:26 GMT;Path=/;'
};
// if ((function() {
// try {
// return !! window.addEventListener;
// } catch(e) {
// return false;
// }
// })()) {
// document.addEventListener('DOMContentLoaded', _N, false)
// } else {
// document.attachEvent('onreadystatechange', _N)
// }
_N()
console.log(document.cookie)
- 第五步:其实到这里document.cookie就已经出来结果了,但是为了请求的时候方便,不写js文件,我们多补一些一点环境,也不多,往下看代码块吧!
var document = {
'cookie': '',
'createElement': createElement,
'attachEvent':attachEvent
};
function attachEvent() { }
function setTimeout(a,b) { }
function createElement(a) {
return {
'firstChild': {'href': 'http://www.python-spider.com/challenge/11'}
}
}
// --------------------------------------------------------------------------以上是补充的环境
var _N = function() {
setTimeout('location.href=location.pathname+location.search.replace(/[\?|&]captcha-challenge/,\'\')', 1500);
document.cookie = '__jsl_clearance=1681177714.791|0|' + (function() {
var _t = [function(_N) {
return _N
},
function(_t) {
return _t
},
(function() {
var _N = document.createElement('div');
_N.innerHTML = '<a href=\'/\'>_1H</a>';
_N = _N.firstChild.href;
var _t = _N.match(/https?:\/\//)[0];
_N = _N.substr(_t.length).toLowerCase();
return function(_t) {
for (var _1H = 0; _1H < _t.length; _1H++) {
_t[_1H] = _N.charAt(_t[_1H])
};
return _t.join('')
}
})(),
function(_N) {
for (var _t = 0; _t < _N.length; _t++) {
_N[_t] = parseInt(_N[_t]).toString(36)
};
return _N.join('')
}],
_N = ['clD', [( - ~~~ {} << -~~~ {}) + ( - ~~~ {} << -~~~ {})], 'V', [( - ~ [] + [] + [[]][0]) + [ - ~ - ~ {}]], 'fq', [( - ~ [] + [] + [[]][0]) + [ - ~ [] - ~ [] - ~ ! /!/ + ( - ~ [] - ~ []) * [ - ~ [] - ~ []]], ( - ~ [] + [] + [[]][0]) + ( - ~ [ - ~ - ~ {}] + [[]][0]), ( - ~ [] + [] + [[]][0]) + [( + !![[][[]]][1])]], 'LBWywKW', [(2 - ~ [ - ~ - ~ {}] + [] + [[]][0])], '%2FZyf', [( - ~ [] + [] + [[]][0]) + ( - ~ [ - ~ - ~ {}] + [[]][0])], '6', [( - ~ [] + [] + [[]][0]) + ( - ~ [ - ~ - ~ {}] + [[]][0])], '_5ffcba442c5fde8c35686219ebab7b37', ( - ~ [ - ~ - ~ {}] + [[]][0]), 'D'];
for (var _1H = 0; _1H < _N.length; _1H++) {
_N[_1H] = _t[[1, 0, 1, 2, 1, 3, 1, 2, 1, 2, 1, 3, 1, 0, 1][_1H]](_N[_1H])
};
return _N.join('')
})() + ';Expires=Tue, 12-Dec-30 09:50:26 GMT;Path=/;'
};
if ((function() {
try {
return !! window.addEventListener;
} catch(e) {
return false;
}
})()) {
document.addEventListener('DOMContentLoaded', _N, false)
} else {
document.attachEvent('onreadystatechange', _N)
}
// ----------------------------------------------------------------------------中间原封不动
_N()
console.log(document.cookie)
- 第六步:折合成一个py文件,我们直接上一圈代码吧!
import execjs
from lxml import etree
import requests
headers = {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cache-Control": "no-cache",
"Connection": "keep-alive",
"Pragma": "no-cache",
"Referer": "https://www.python-spider.com/challenge/11",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
"sec-ch-ua": "\"Google Chrome\";v=\"111\", \"Not(A:Brand\";v=\"8\", \"Chromium\";v=\"111\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\""
}
cookies = {
"Hm_lvt_337e99a01a907a08d00bed4a1a52e35d": "1680083861,1680774930,1680847426,1681090834",
"Hm_lpvt_337e99a01a907a08d00bed4a1a52e35d": "1681093340",
"sessionid": "ci7mztgcri9udzsoej78jt6c0szyfpqn",
}
url = "https://www.python-spider.com/challenge/11"
response = requests.get(url, headers=headers, cookies=cookies)
print(response.text)
print(response)
response_JS = response.text[8:-9]
response_JS = response_JS.replace('eval', 'JSCode = ')
print('eval改变量 -->>>', response_JS)
Golab_Var = """
var document = {
'cookie': '',
'createElement': createElement,
'attachEvent':attachEvent
};
function setTimeout(a,b) { }
function attachEvent() { }
function createElement(a) {
return {
'firstChild': {'href': 'http://www.python-spider.com/challenge/11'}
}
}
"""
End_JS = """
function get_cookie() {
eval(JSCode);
_N();
console.log('document -->>', document.cookie)
__jsl_clearance = document.cookie.split(';')[0].split('=')[1]
return __jsl_clearance
}
"""
str_JS = Golab_Var + response_JS + End_JS
js = execjs.compile(str_JS) # 加载 JS 代码
result = js.call("get_cookie")
print(result)
cookies['__jsl_clearance']=result
url = "https://www.python-spider.com/challenge/11"
response1 = requests.get(url, headers=headers, cookies=cookies)
print(response1.text)
print(response1)