Python爬虫,请求参数加密怎么办?

目录

背景介绍:

目标网址:

页面分析:

逆向解析加密参数思路

代码实现:

code_js.js

JS方式实现

python代码实现

总结:

                                   我是政胤 期待你的关注


背景介绍:

大家好 我是政胤.

我们在请求接口的时候,发现请求参数数加密的,该如何处理呢?今天介绍两种方式完成请求参数解密,一种是通过调试js,逆向解析的方式,另一种是Python方式实现解析请求参数。

目标网址:

https://www.oklink.com/zh-cn/btc/tx-list?limit=20&pageNum=1

页面分析:

确定数据接口地址

Python爬虫,请求参数加密怎么办?_第1张图片

确定请求头和请求参数有没有加密

Python爬虫,请求参数加密怎么办?_第2张图片

Python爬虫,请求参数加密怎么办?_第3张图片

确定返回的数据是不是加密

Python爬虫,请求参数加密怎么办?_第4张图片

逆向解析加密参数思路

定位到加密参数所在哪个js文件

Python爬虫,请求参数加密怎么办?_第5张图片

Python爬虫,请求参数加密怎么办?_第6张图片

在来源面板中打开js

Python爬虫,请求参数加密怎么办?_第7张图片

确定加密参数所在位置

Python爬虫,请求参数加密怎么办?_第8张图片

打断点,刷新页面

Python爬虫,请求参数加密怎么办?_第9张图片

确定getApiKey方法的位置

Python爬虫,请求参数加密怎么办?_第10张图片

改写js

Python爬虫,请求参数加密怎么办?_第11张图片

Python爬虫,请求参数加密怎么办?_第12张图片

补全js代码,并改成成函数

Python爬虫,请求参数加密怎么办?_第13张图片

运行js

Python爬虫,请求参数加密怎么办?_第14张图片

Python爬虫,请求参数加密怎么办?_第15张图片

Python爬虫,请求参数加密怎么办?_第16张图片

Python爬虫,请求参数加密怎么办?_第17张图片

代码实现:

code_js.js

function getApiKey() {
    var t = (new Date).getTime()
      , e = encryptApiKey();
    return t = encryptTime(t),
    comb(e, t)
}
// encryptApiKeya
function encryptApiKey() {
    var t = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
      , e = t.split("")
      , r = e.splice(0, 8);
    return e.concat(r).join("")
}
// encryptApiKey
function encryptTime(t) {
    var e = (1 * t + 1111111111111).toString().split("")
      , r = parseInt(10 * Math.random(), 10)
      , n = parseInt(10 * Math.random(), 10)
      , o = parseInt(10 * Math.random(), 10);
    return e.concat([r, n, o]).join("")
}
// comb
function comb(t, e) {
    var r = "".concat(t, "|").concat(e);
    return btoa(r)
}

// 调用函数运行
// console.log(getApiKey())

JS方式实现

import requests
import json
import execjs
from jsonpath import jsonpath
import time


# 第一页 https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?t=1657362656709&limit=20&offset=0
# 第二页 https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?t=1657362632969&limit=20&offset=20
# 第三页 https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?t=1657362567236&limit=20&offset=40
# 第四页 https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?t=1657362796076&limit=20&offset=60

def parse(offset):
    ## 目标地址:'https://www.oklink.com/zh-cn/btc/tx-list?limit=20&pageNum=1'
    with open('./code_js.js', 'r', encoding='utf-8') as f:
        js_code = f.read()
    # compile 调用文件,call 调用getApiKey函数
    apiKey = execjs.compile(js_code).call('getApiKey')
    # print(apiKey)
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
        'x-apiKey': apiKey
    }
    # t 是当前时间的数据戳
    t = str(time.time() * 1000)[:-5]
    # print(t)
    data = {
        't': t,
        'limit': 20,
        'offset': offset
    }
    # 数据接口地址
    url = 'https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict'
    res = requests.get(url, headers=header, params=data).text
    # json字符串数据,转为python字典数据
    dict_data = json.loads(res)
    # print(json_data)
    # 数据提取
    # 交易哈希
    hash_list = jsonpath(dict_data, "$..hash")
    # 所在区块
    blockHeight_list = jsonpath(dict_data, "$..blockHeight")
    # 数量(BTC)
    inputsValue_list = jsonpath(dict_data, "$..inputsValue")
    # 手续费(BTC)
    fee_list = jsonpath(dict_data, "$..fee")
    print(hash_list, blockHeight_list, inputsValue_list, fee_list)


# 爬取3页
for i in range(1, 4):
    print(f'正在爬取第{i}页')
    offset = (i - 1) * 20
    parse(offset)

python代码实现

import base64
import random

import requests
import json
from jsonpath import jsonpath
import time

def getApiKey():
    # 13位的时间戳
    t = int(str(time.time() * 1000)[:-5])
    e = encryptApiKey()
    # print('t的值', e)
    t = encryptTime(t)
    # print('e的值', t)
    return comb(e, t)


def encryptApiKey():
    t = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
    # e是t后28个字符组成的列表
    e = [j for j in t[8:]]
    # r是前8个字符组成的列表
    r = [j for j in t[:8]]
    # 返回值就是 e拼接r组成的字符串
    e.extend(r)
    return ''.join(e)


def encryptTime(t):
    # e 为 (1 * t + 1111111111111)的结果转为字符串的每个字符组成的列表
    e = [j for j in str(1 * t + 1111111111111)]
    #  r、n、o 为 随机数字(0-9)
    r = str(random.randint(0, 9))
    n = str(random.randint(0, 9))
    o = str(random.randint(0, 9))
    # 返回的结果是 e,r, n, o 拼接后的字符串
    e.extend(list(r + o + n))
    return ''.join(e)


def comb(t, e):
    # r 是t 和"|" 和e 拼接之后的字符串
    r = t + '|' + e
    # 返回的是base64编码的字符串
    return base64.b64encode(r.encode()).decode()


def parse(offse):
    apikey = getApiKey()
    print(apikey)
    # print(apiKey)
    header = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
        'x-apiKey': apikey
    }
    # t 是当前时间的数据戳
    t = str(time.time() * 1000)[:-5]
    # print(t)
    data = {
        't': t,
        'limit': 20,
        'offset': offse
    }
    # 数据接口地址
    url = 'https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict'
    res = requests.get(url, headers=header, params=data).text
    # json字符串数据,转为python字典数据
    dict_data = json.loads(res)
    # print(json_data)
    # 数据提取
    # 交易哈希
    hash_list = jsonpath(dict_data, "$..hash")
    # 所在区块
    blockHeight_list = jsonpath(dict_data, "$..blockHeight")
    # 数量(BTC)
    inputsValue_list = jsonpath(dict_data, "$..inputsValue")
    # 手续费(BTC)
    fee_list = jsonpath(dict_data, "$..fee")
    print(hash_list, blockHeight_list, inputsValue_list, fee_list)


# 爬取3页
for i in range(1, 3):
    print(f'正在爬取第{i}页')
    offset = (i - 1) * 20
    parse(offset)

总结:

通过这个案例,我们可以知道怎样确定数据接口地址,怎样确定加密参数所在哪个js文件以及了解js调试过程。通过调试js逆向解析的方式和Python方式均可实现请求参数解析。python实现的原理就是将js的写函数用python的方式来写。

                                   我是政胤 期待你的关注

Python爬虫,请求参数加密怎么办?_第18张图片

你可能感兴趣的