知识点:
1、请求头加密参数分析
2、JS base64加密的多个实现方法
目标网站:aHR0cHM6Ly93d3cub2tsaW5rLmNvbS96aC1jbi9idGMvdHgtbGlzdD9saW1pdD0yMCZwYWdlTnVtPTE=
通过抓包分析请求,不难发现,该网站的请求头headers里有一个参数x-apiKey。
搜索x-apiKey,再index.js文件找到如下结果:
index.js文件里搜索 getApiKey,不难发现,getApiKey由comb函数处理e,t两个 参数,而comb函数 就是对参数拼接后进行base64编码(如图方框处btoa)。
这样只要找到两个参数的来源,就解决问题了。
从上图不难发现, 两个参数的生成位置:
通过搜索encryptApiKey和encryptTime两个函数名,不难找出其生成原理。
抠出上述js代码,新建js文件okyunlian.js,并写一个生成x-apiKey参数的函数入口
get_x_apiKey()。js文件如下:
// const CryptoJS =require('crypto-js')
const CryptoJS=require('D:\\nodejs\\node_modules\\crypto-js\\crypto-js')
function encryptApiKey() {
API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
var t = API_KEY
, e = t.split("")
, r = e.splice(0, 8);
return e.concat(r).join("")
}
function encryptTime(t) {
o = 1111111111111
var e = (1 * t + o).toString().split("")
, r = parseInt(10 * Math.random(), 10)
, n = parseInt(10 * Math.random(), 10)
, i = parseInt(10 * Math.random(), 10);
return e.concat([r, n, i]).join("")
}
function comb(t, e) {
var r = "".concat(t, "|").concat(e);
base64 = Buffer.from(r, 'utf-8').toString('base64') //base64 加密
// console.log(base64)
// 另一种方法加密
var str=CryptoJS.enc.Utf8.parse(r);
var base64=CryptoJS.enc.Base64.stringify(str)
// console.log(base64)
return base64
}
function get_x_apiKey(){
t=(new Date).getTime()
t=encryptTime(t)
// console.log(t)
e = encryptApiKey()
x_apiKey=comb(e,t)
console.log(x_apiKey)
return x_apiKey
}
// console.log(get_x_apiKey())
// console.log(module.paths)
对应的python代码如下:
import requests,json,csv,time,execjs
x_apiKey=execjs.compile(open('./okyunlian.js','r',encoding='utf-8').read()).call('get_x_apiKey')
# print(x_apiKey)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36',
'x-apiKey': x_apiKey
}
url='https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict'
def main():
for page in range(1,4):
# print(page)
params = {
't': str(int(time.time()*1000)),
'limit': '20',
'offset': (page-1)*20,
}
res=requests.get(url=url,params=params,headers=headers,timeout=2)
print(res.status_code)
json_data=res.json()['data']['hits']
print(json_data)
# json_data=json.loads(res.text)
# print(json_data)
if __name__=='__main__':
main()
爬取结果如下: