知识点:
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()
爬取结果如下: