import requests
# 调用js报错时,修改默认编码格式
import subprocess
from functools import partial
subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")
import execjs
request_data = "{\"limit\":\"20\",\"page\":\"2\"}"
#请求参数加密
with open("bird.js", "r", encoding='utf-8') as f:
data = f.read()
js = execjs.compile(data)
res = js.call("sign", request_data)
requestId = res.get('requestId')
sign = res.get('sign')
timestamp = res.get('timestamp')
request_sign_data = res.get('data')
url = "https://api.birdreport.cn/front/activity/search"
headers = {
"Origin":
"http://birdreport.cn",
"Requestid":requestId,
"Sign":sign,
"Timestamp":timestamp,
"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36",
"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"
}
response = requests.post(url=url,headers=headers,data=request_sign_data)
response_data = response.json().get('data')
#返回数据解密
with open("data.js", "r", encoding='utf-8') as f:
data = f.read()
js = execjs.compile(data)
res = js.call("g", response_data)
print(res)
python 调用js报错时添加:
import subprocess
from functools import partial
subprocess.Popen = partial(subprocess.Popen, encoding="utf-8")
对应的bird.js
global.window = {};
const JSEncrypt = require('jsencrypt');
const MD5 = require('md5');
function getUuid() {
var s = [];
var a = "0123456789abcdef";
for (var i = 0; i < 32; i++) {
s[i] = a.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = "4";
s[19] = a.substr((s[19] & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23];
var b = s.join("");
return b
}
function sign(data) {
var paramPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvxXa98E1uWXnBzXkS2yHUfnBM6n3PCwLdfIox03T91joBvjtoDqiQ5x3tTOfpHs3LtiqMMEafls6b0YWtgB1dse1W5m+FpeusVkCOkQxB4SZDH6tuerIknnmB/Hsq5wgEkIvO5Pff9biig6AyoAkdWpSek/1/B7zYIepYY0lxKQIDAQAB";
var encrypt = new JSEncrypt();
encrypt.setPublicKey(paramPublicKey);
var c = Date.parse(new Date());
var d = getUuid();
var signdata = encrypt.encrypt(data + "\u0000");
var str = c.toString();
var f = MD5(data+d+str);
return {
"data":signdata,
"sign":f,
"timestamp":str,
"requestId":d
}
}
对应的data.js
const CryptoJS = require('crypto-js');
const AES = require('crypto-js/aes');
const enc = require('crypto-js/enc-utf8');
function g(a){
var key = '3583ec0257e2f4c8195eec7410ff1619';
var iv = 'd93c0d5ec6352f20';
var b = CryptoJS.enc.Utf8.parse(key);
var c = CryptoJS.enc.Utf8.parse(iv);
var d = CryptoJS.AES.decrypt(a, b, {
iv: c,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return d.toString(CryptoJS.enc.Utf8)
}
调用后输出的结果: