第五题可以发现请求方式变成了post请求
可以看到请求的信息变成了一串加密的内容
通过搜索得到两个js文件,但只有一个js文件有xl
点击进去查看,发现:
xl ——> encryptedQuery ——> encrypt(jsonString) 然后encrypt(jsonString)就开始各种混淆了
这里个人懒得去理解上面的内容了
直接把整个文件存到本地,编辑loadPage改一下,让他只返回xl信息
通过Python的execjs去调js
js代码:
// 这个需要npm install crypto-js安装
const CryptoJS = require('crypto-js');
// 这下面没有改过,只有末尾函数改过
const _0x38addf = _0x66a7;
function _0x66a7(_0x7461a9, _0x14ffcc) {
const _0x4f0d09 = _0x4f0d();
return _0x66a7 = function (_0x66a780, _0x2abc15) {
_0x66a780 = _0x66a780 - 0xc5;
let _0x477d8f = _0x4f0d09[_0x66a780];
return _0x477d8f;
}, _0x66a7(_0x7461a9, _0x14ffcc);
}
(function (_0x59b24b, _0x16d38a) {
const _0x3e5f1c = _0x66a7, _0x14ae46 = _0x59b24b();
while (!![]) {
try {
const _0x5e1110 = parseInt(_0x3e5f1c(0xca)) / 0x1 + -parseInt(_0x3e5f1c(0xd4)) / 0x2 * (-parseInt(_0x3e5f1c(0xd5)) / 0x3) + parseInt(_0x3e5f1c(0xc8)) / 0x4 + -parseInt(_0x3e5f1c(0xcc)) / 0x5 * (-parseInt(_0x3e5f1c(0xd0)) / 0x6) + -parseInt(_0x3e5f1c(0xd3)) / 0x7 + -parseInt(_0x3e5f1c(0xcd)) / 0x8 + -parseInt(_0x3e5f1c(0xcf)) / 0x9;
if (_0x5e1110 === _0x16d38a) break; else _0x14ae46['push'](_0x14ae46['shift']());
} catch (_0x4fbd75) {
_0x14ae46['push'](_0x14ae46['shift']());
}
}
}(_0x4f0d, 0x897b4), dd = {'a': CryptoJS});
let key = dd['a'][_0x38addf(0xd6)][_0x38addf(0xc7)][_0x38addf(0xc9)](_0x38addf(0xce)),
iv = dd['a'][_0x38addf(0xd6)]['Utf8'][_0x38addf(0xc9)]('0123456789ABCDEF');
function _0x4f0d() {
const _0x341c37 = ['2440720SaQcQw', 'jo8j9wGw%6HbxfFn', '9735516pjwmiO', '68862pbatqQ', 'mode', 'AES', '1923264HnviQd', '36906bPsIrd', '12hEJHOd', 'enc', 'pad', 'encrypt', 'Hex', 'Utf8', '689460JbShaf', 'parse', '957060HmuxSn', 'toString', '445UZKyxv'];
_0x4f0d = function () {
return _0x341c37;
};
return _0x4f0d();
}
function encrypt(jsonString) {
const _0x4d843e = _0x38addf;
let _0x2703a2 = dd['a'][_0x4d843e(0xd6)]['Utf8']['parse'](jsonString),
_0x50fcf0 = dd['a'][_0x4d843e(0xd2)][_0x4d843e(0xc5)](_0x2703a2, key, {
'mode': dd['a'][_0x4d843e(0xd1)]['CBC'],
'padding': dd['a'][_0x4d843e(0xd7)]['Pkcs7'],
'iv': iv
});
return _0x50fcf0['ciphertext'][_0x4d843e(0xcb)](CryptoJS[_0x4d843e(0xd6)][_0x4d843e(0xc6)]);
}
// 上面不变,此函数有改动
function loadPage(timestamp, pageNumber) {
const params = {page: pageNumber, _ts: timestamp};
const jsonString = JSON.stringify(params);
let encryptedQuery = encrypt(jsonString);
return encryptedQuery
}
// 调试代码
const timestamp = new Date().getTime();
console.log(loadPage(timestamp, 1))
python代码:
import json
import time
import execjs
import requests
# 读取本地js文件
with open('xl.js', encoding='utf-8') as f:
js_code = f.read()
def request_page(sessionid: str, page: int):
"""
请求对应页码信息
:param sessionid: 用户session信息
:param page: 页码
:return: 结果列表
"""
timestamp = int(time.time() * 1000)
page_url = "https://stu.tulingpyton.cn/api/problem-detail/5/data/"
headers = {
# 标识登录用户
"cookie": f"sessionid={sessionid}"
}
xl = execjs.compile(js_code).call('loadPage', timestamp, page)
body = {"xl": xl}
# 可以不加的,一般执行一次不会报错,除非你连续执行了多次可能出现:访问频率过快,请稍后再试
while True:
try:
return requests.post(page_url, headers=headers, data=json.dumps(body)).json()['current_array']
except:
print(requests.post(page_url, headers=headers, data=json.dumps(body)).json()['error'])
time.sleep(60)
if __name__ == '__main__':
user_session = 'xxxxxxxxxx'
number = 0
for i in range(1, 21):
number += sum(request_page(user_session, i))
print(number)
得到结果
注意!!!不要请求太频繁,会被封的,不要问为什么,全是泪