Python crawler simple js reverse


Dado que la tarea de aprendizaje requiere rastreadores para obtener datos, aprendí los conceptos básicos de los rastreadores de Python.
Pero cuando comencé a escribir el programa rastreador, había un problema y la solución se registra de la siguiente manera.

breve introducción

Requisitos: rastrear los datos de un sitio web de blockchain financiero https://www.oklink.com/btc/tx-list .

Hay un problema: los datos de rastreo primero deben enviar una solicitud para obtener los datos de respuesta. A través del análisis de la página web, sabemos que los datos que deben obtenerse provienen de la carga dinámica de ajax, por lo que elijo obtener los datos de respuesta enviando una solicitud a la URL de ajax. El parámetro en el encabezado de la solicitud de la solicitud es el problema principal que debe resolverse. Sin embargo, el encabezado de solicitud ajax de la solicitud a los datos contiene parámetros encriptados y que cambian dinámicamente similares a los siguientes

xapiKey:LWIzMWUtNDU0Ny05Mjk5LWI2ZDA3Yjc2MzFhYmEyYzkwM2NjfDI3MTk0ODY0MDUwNzA2Mjk=

Solución: Analice los archivos js relacionados solicitados por el navegador para obtener la función de generación x-apiKey y vuelva a escribirlo con python (no es necesario que vuelva a escribir, también puede ejecutar el código js llamando a la biblioteca js relevante en python).

1. Busque el paquete de datos ajax que contiene los datos necesarios

  1. Abra el sitio web, abra la herramienta del navegador con la tecla de acceso directo Ctrl + shift + I, seleccione Red-> XHR, actualice la página web, puede ver que solo hay un paquete de solicitud:
    Solicitar paquete

  2. Después de abrir, puede encontrar la URL solicitada:
    url

     https://www.oklink.com/api/explorer/v1/btc/transactionsNoRestrict?t=1608475589424&limit=20&offset=0
    
  3. Explicación de los parámetros en la URL de ajax:

     1. get请求
     2. t=1608475589424 为 时间戳
     3. limit=20 为每页的交易数量
     4. offset=0 为每页的起始交易位置
    
  4. Los parámetros contenidos en el encabezado de la solicitud se pueden encontrar a continuación:
    Encabezado de solicitud

  5. X-apiKey es el parámetro encriptado en el encabezado de la solicitud y cambia cada vez que se actualiza.

     x-apiKey: LWIzMWUtNDU0Ny05Mjk5LWI2ZDA3Yjc2MzFhYmEyYzkwM2NjfDI3MTk1ODY3MDA1MzExODU=
    

2. Posicionamiento de palabras clave a través de herramientas de navegador

  1. Busque Buscar en la parte superior derecha:
    Encuentra herramientas
  2. Entrada: x-apiKey, se encuentran tres resultados, como se muestra en la figura
    Detalles
  3. Puede ver que el encabezado se incluye después del tercer archivo js, ​​ábralo.
    Aquí puede hacer clic en el siguiente {} para formatear el código:
    Inserte la descripción de la imagen aquí
  4. Presione la tecla de método abreviado Ctrl + F para encontrar la x-apiKey en el archivo js nuevamente y
    ubique la x-apiKey, luego saque el segmento de código asociado:
function(t, e, n) {
    
    
    "use strict";
    n(115),
    n(57),
    n(20),
    n(60);
    function r(t, e) {
    
    
        for (var n = 0; n < e.length; n++) {
    
    
            var r = e[n];
            r.enumerable = r.enumerable || !1,
            r.configurable = !0,
            "value"in r && (r.writable = !0),
            Object.defineProperty(t, r.key, r)
        }
    }
    var o = new (function() {
    
    
        function t() {
    
    
            !function(t, e) {
    
    
                if (!(t instanceof e))
                    throw new TypeError("Cannot call a class as a function")
            }(this, t),
            this.API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
        }
        return function(t, e, n) {
    
    
            e && r(t.prototype, e),
            n && r(t, n)
        }(t, [{
    
    
            key: "encryptApiKey",
            value: function() {
    
    
                var t = this.API_KEY
                  , e = t.split("")
                  , n = e.splice(0, 8);
                return t = e.concat(n).join("")
            }
        }, {
    
    
            key: "encryptTime",
            value: function(t) {
    
    
                var e = (1 * t + 1111111111111).toString().split("")
                  , n = parseInt(10 * Math.random(), 10)
                  , r = parseInt(10 * Math.random(), 10)
                  , o = parseInt(10 * Math.random(), 10);
                return e.concat([n, r, o]).join("")
            }
        }, {
    
    
            key: "comb",
            value: function(t, e) {
    
    
                var n = "".concat(t, "|").concat(e);
                return window.btoa(n)
            }
        }, {
    
    
            key: "getApiKey",
            value: function() {
    
    
                var t = (new Date).getTime()
                  , e = this.encryptApiKey();
                return t = this.encryptTime(t),
                this.comb(e, t)
            }
        }]),
        t
    }())
      , i = window.utils.ont
      , c = Object.assign({
    
    }, i);
    c.interceptors.request.use(function(t) {
    
    
        return t.url.indexOf("api/explorer/v1") > -1 && (t.headers.common["x-apiKey"] = o.getApiKey()),
        t
    });
    e.a = c
}

3. Analice los archivos js relacionados para averiguar la implementación específica

Obviamente, x-apiKey es la variable o obtenida llamando a la función getApiKey ()

t.headers.common["x-apiKey"] = o.getApiKey()

1. función getApiKey ()

Encuentra la definición de la función:

key: "getApiKey",
value: function() {
    
    
	var t = (new Date).getTime()
 	  , e = this.encryptApiKey();
	return t = this.encryptTime(t),
	this.comb(e, t)
	}
  1. La variable t es la hora actual y la variable e se obtiene llamando a encryptApiKey ();
  2. Después de pasar la variable t como parámetro a la función encryptTime (), se obtiene una nueva variable t;
  3. Finalmente, la variable ty la variable e se pasan como parámetros a la función comb () para obtener el valor de retorno final x-apiKey.

2. La función encryptApiKey ()

key: "encryptApiKey",
value: function() {
    
    
	var t = this.API_KEY
      , e = t.split("")
      , n = e.splice(0, 8);
   return t = e.concat(n).join("")
   }
  1. La variable t es una cadena fija, que se puede encontrar arriba

     this.API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
    
  2. La variable e es cortar la variable t para obtener cada carácter en t, y la variable n obtiene los primeros 8 caracteres en e, a saber:

     "a", "2", "c", "9", "0", "3", "c", "c"
    
  3. La variable final t es eliminar la n parte de e y agregarle n para obtener el nuevo valor de retorno de cadena

    "-b31e-4547-9299-b6d07b7631aba2c903cc"
    

    Este valor es el parámetro e de la función comb () en la función getApiKey ().

3. La función encryptTime ()

key: "encryptTime",
value: function(t) {
    
    
	var e = (1 * t + 1111111111111).toString().split("")
      , n = parseInt(10 * Math.random(), 10)
      , r = parseInt(10 * Math.random(), 10)
      , o = parseInt(10 * Math.random(), 10);
	return e.concat([n, r, o]).join("")
	}
  1. t es la hora actual entrante (marca de tiempo de 13 bits), que se pasa ae después del procesamiento de la cadena;

  2. Las variables n, r, o se generan números enteros aleatorios de 0 a 10, combinados con e para generar una nueva cadena sobre el tiempo actual y 3 números aleatorios, como

     "2", "7", "1", "9", "4", "9", "2", "4", "3", "8", "8", "9", "9"]
    

    Este valor es el parámetro t de la función comb () en la función getApiKey ().

4. Función peine ()

key: "comb",
value: function(t, e) {
    
    
	var n = "".concat(t, "|").concat(e);
	return window.btoa(n)
    }
  1. La variable n son los parámetros entrantes ty e después del procesamiento

     2719492921233667|-b31e-4547-9299-b6d07b7631aba2c903cc
    
  2. window.btoa (n) es la función de cifrado base64, obtenga el n cifrado

     MjcxOTQ5MzI5ODc0MjA2NXwtYjMxZS00NTQ3LTkyOTktYjZkMDdiNzYzMWFiYTJjOTAzY2M=
    
  3. Compare la x-apiKey en el encabezado de la solicitud del navegador

     LWIzMWUtNDU0Ny05Mjk5LWI2ZDA3Yjc2MzFhYmEyYzkwM2NjfDI3MTk0ODc1Mzk0ODMwOTE=
    

    Se puede ver que existen inconsistencias más obvias.

5. Encuentre la causa de la inconsistencia

  1. Decodifica la x-apiKey obtenida en el navegador a través de base64

     -b31e-4547-9299-b6d07b7631aba2c903cc|2719487539483091
    
  2. Y la cadena antes del cifrado obtenida mediante el proceso anterior es

     2719492921233667|-b31e-4547-9299-b6d07b7631aba2c903cc
    
  3. Se puede observar fácilmente que la diferencia entre los datos antes del cifrado y los datos correctos generados por nosotros mismos es el orden de las cadenas antes y después de "|";

  4. Después de modificar la secuencia, se obtiene el resultado correcto.

6. Vuelva a escribir el código js anterior en código Python

# 获取动态变化且加密的x-apiKey
def get_x_apikey():
    # API_KEY固定字符串
    API_KEY = "a2c903cc-b31e-4547-9299-b6d07b7631ab"
    Key1 = API_KEY[0:8]
    Key2 = API_KEY[8:]
    #  交换API_KEY部分内容
    new_Key = Key2 + Key1
    # 获取当前时间,毫秒级
    cur_time = round(time.time() * 1000)
    # 处理获得的时间
    new_time = str(1 * cur_time + 1111111111111)
    # 生成三个0-9的随机整数
    random1 = str(random.randint(0, 9))
    random2 = str(random.randint(0, 9))
    random3 = str(random.randint(0, 9))
    # 再次处理时间字符串
    cur_time = new_time + random1 + random2 + random3
    # 将包含API_KEY和时间串的内容合并
    this_Key = new_Key + '|' + cur_time
    # 转码
    n_k = this_Key.encode('utf-8')
    # base64加秘
    x_apiKey = base64.b64encode(n_k)
    # 将加密后的x_apiKey返回
    return str(x_apiKey, encoding='utf8')

Hasta ahora, este trabajo inverso de js se ha resuelto con éxito.

Supongo que te gusta

Origin blog.csdn.net/qq_47935193/article/details/111408643
Recomendado
Clasificación