¡Artefacto de reptil! Úselo para procesar y guardar datos Ajax en tiempo real

A menudo nos encontramos con un problema de este tipo cuando hacemos rastreadores:

Los datos del sitio web se cargan a través de Ajax, pero la interfaz Ajax está encriptada y no se puede descifrar sin ningún esfuerzo. En este momento, si queremos evitar el craqueo y capturar datos, por ejemplo, tenemos que usar Selenium. Selenium puede completar algunas operaciones como simular clics y pasar de página, pero no es fácil obtener datos Ajax. Los datos se extraen a través del HTML renderizado. muy problemático.

Quizás pensarás para ti mismo: si tan solo pudiera usar Selenium para manejar la página y al mismo tiempo guardar los datos solicitados por Ajax.

Naturalmente, hay una manera, por ejemplo, de agregar una capa de agentes, simplemente use mitmdump para el procesamiento en tiempo real.

Pero si no hay un agente, ¿no hay una buena forma?

Aquí presentamos una herramienta llamada AjaxHook, con la cual podemos interceptar todos los datos solicitados por Ajax, siempre que ocurra una solicitud Ajax, puede interceptar la solicitud y respuesta, para que podamos lograr el procesamiento en tiempo real de los datos Ajax. .

Gancho Ajax

Hook no es ajeno a todo el mundo, no entraré aquí. Si no lo entiende, puede buscar "Hook Technology" y puede encontrar un puñado de información.

Entonces Ajax Hook, como su nombre lo indica, es Hook Ajax request. ¿Las dos partes más importantes de Ajax? Por supuesto, es Solicitud y Respuesta. Con Hook, podemos procesar tanto antes de iniciar Solicitud como después de obtener Respuesta.

El punto de acción básico se muestra en la figura:

Entonces, ¿cómo hacemos solicitudes de Hook Ajax? Entonces, naturalmente, debe profundizar en la implementación nativa de Ajax. En realidad, Ajax se implementa mediante el uso del objeto XMLHttpRequest. Para conectar la solicitud y la respuesta de Ajax, en realidad está procesando algunos de sus atributos, como enviar, onreadystatechange, etc.

Suena problemático, no te preocupes, alguien ya ha escrito esto, solo lo usamos directamente, la dirección de GitHub es: https://github.com/wendux/Ajax-hook.

De hecho, el principio de implementación interna es muy simple. De hecho, lo acabo de mencionar brevemente. Si quieres entenderlo en profundidad, puedes leer este artículo: https://www.jianshu.com/p/7337ac624b8e.

OK, ¿cómo usas esto?

El autor de Ajax-hook proporciona dos métodos principales, uno es proxy y el otro es hook, todos los cuales funcionan mediante Hook XMLHttpRequest.

Aquí está la introducción oficial:

Se pueden utilizar métodos de enlace y proxy para interceptar la XMLHttpRequest global. La diferencia entre ellos es que la granularidad de intercepción de los ganchos está bien, que puede ser específica de un determinado método, atributo y devolución de llamada del objeto XMLHttpRequest, pero es más problemático de usar. En muchos casos, no solo la lógica empresarial debe estar dispersa entre las devoluciones de llamada, sino que también es propensa a errores. El proxy tiene un alto grado de abstracción y construye un contexto de solicitud. La configuración de la información de solicitud se puede obtener directamente en cada devolución de llamada, lo que es más simple y más eficiente de usar.

En la mayoría de los casos, recomendamos utilizar el método de proxy a menos que el método de proxy no pueda satisfacer sus necesidades.

Entonces echemos un vistazo al uso del método proxy, su uso es el siguiente:

proxy ({
    //请求发起前进入
    onRequest: (config, handler) => {
        console.log(config.url)
        handler.next(config);
    },
    //请求发生错误时进入,比如超时;注意,不包括http状态码错误,如404仍然会认为请求成功
    onError: (err, handler) => {
        console.log(err.type)
        handler.next(err)
    },
    //请求成功后进入
    onResponse: (response, handler) => {
        console.log(response.response)
        handler.next(response)
    }
})

Está claro que Ajax-hook nos proporciona tres métodos de replicación, onRequest, onResponse y onError son el procesamiento antes de que se inicie la solicitud, el procesamiento después de que la solicitud sea exitosa y el procesamiento cuando ocurre un error.

Entonces, si queremos hacer un rastreo de datos, en realidad es para interceptar los resultados de Response, entonces es realmente bueno implementar el método onResponse.

Eche un vistazo más de cerca. Este método onResponse recibe dos parámetros, el objeto de respuesta y el objeto de controlador. Todos estos están encapsulados por Ajax-hook para nosotros. De hecho, solo necesitamos usar el contenido en la respuesta, como el Cuerpo de respuesta Imprimirlo es en realidad imprimir los resultados obtenidos por Ajax.

Bien, entonces probémoslo.

Introducción al caso

Tomemos un caso propio, el enlace es: https://dynamic2.scrape.center/, la interfaz es la siguiente:

Este sitio web es un sitio web de datos de películas. Los datos se cargan a través de Ajax, pero estas solicitudes de Ajax llevan tokens de parámetros cifrados, como se muestra en la figura:

De hecho, no es difícil para usted resolver este parámetro, pero llevará algún tiempo.

Luego mire el resultado de retorno de Ajax, como se muestra en la figura:

¡Muy puro y claro! Entonces, si podemos obtener estos datos directamente cuando obtenemos la respuesta Ajax, sería algo bueno.

¿Cómo hacer? Naturalmente, se utiliza el gancho Ajax que acabamos de mencionar.

Entonces, usemos este gancho Ajax para procesar estos datos en tiempo real.

Operación real

En primer lugar, el primer paso es que tenemos que poder usar Ajax-hook, ¿cómo usarlo? Debe ser necesario introducir esta librería Ajax-hook ¿Cómo introducir esta página en el navegador?

Hay muchas respuestas, como copiar JavaScript, Tampermonkey, Selenium, etc.

Aquí usamos el método más simple, Selenium ejecuta automáticamente el código fuente de Ajax-hook.

En este momento, necesitamos encontrar el código fuente de Ajax-hook. Vaya a GitHub y búsquelo. El enlace es: https://raw.githubusercontent.com/wendux/Ajax-hook/master/dist/ajaxhook.min.js , como muestra la imagen:

Mira, la cantidad de código es muy pequeña.

Copiamos y pegamos este código en la consola del sitio web https://dynamic2.scrape.center/.

En este momento obtendremos un objeto ah, que representa el gancho Ajax, y podemos usar el método proxy en él.

¿Cómo usarlo? Simplemente implemente el método onResponse directamente e imprima el resultado de la Respuesta. La implementación es la siguiente:

ah.proxy({
    //请求成功后进入
    onResponse: (response, handler) => {
        if (response.config.url.startsWith('/api/movie')) {
            console.log(response.response)
            handler.next(response)
        }
    }
})

Coloque este código en la consola y ejecútelo. En este momento, hemos implementado el Hook of Ajax Response. Siempre que haya una solicitud Ajax, se mostrará el resultado de la Respuesta.

En este momento, si hacemos clic para pasar la página y activar una nueva solicitud Ajax, podemos ver que la consola genera el resultado de Respuesta, como se muestra en la figura:

Bueno, ahora podemos obtener datos de Ajax.

Reenvío de datos

Ahora que los datos están en el navegador, ¿cómo los guardamos?

No es fácil de guardar, la forma más fácil es enviar estos datos a una de sus propias interfaces y guardarlos.

Entonces, simplemente usemos Flask para hacer una interfaz, recuerde levantar la restricción entre dominios, la implementación es la siguiente:

import json
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/receiver/movie', methods=['POST'])
def receive():
    content = json.loads(request.data)
    print(content)
    # to something
    return jsonify({'status': True})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

Aquí solo escribí un ejemplo simple, escribí una API que puede recibir solicitudes POST, la dirección es / receptor / película, y luego imprimo los datos POST y devuelve una respuesta.

Por supuesto, aquí puede realizar muchas operaciones, como cortar datos y almacenarlos en una base de datos.

Bien, ahora que el servidor está disponible, enviemos los datos por el lado del gancho Ajax.

Aquí usamos la biblioteca axios, cuya dirección de biblioteca es https://unpkg.com/[email protected]/dist/axios.min.js, que también se puede usar cuando se ejecuta en un navegador.

Después de introducir axios, modificamos el método proxy anterior a lo siguiente:

ah.proxy({
    //请求成功后进入
    onResponse: (response, handler) => {
        if (response.config.url.startsWith('/api/movie')) {
            axios.post('http://localhost/receiver/movie', {
                url: window.location.href,
                data: response.response
            })
            console.log(response.response)
            handler.next(response)
        }
    }
})

De hecho, aquí es para llamar al método de publicación de axios, y luego enviar la URL actual y los datos de respuesta al servidor.

Hasta ahora, el resultado de la respuesta de cada solicitud Ajax se enviará a este Flask Server, y Flask Server lo almacenará y procesará.

automatización

Bien, ahora podemos lograr la interceptación de Ajax y el reenvío de datos, el último paso es, naturalmente, automatizar el rastreo.

La automatización se divide en tres partes:

  • Abrir sitio web
  • Inyecte el código de Ajax-hook, axios y proxy.
  • Haga clic automáticamente en la página siguiente para pasar la página.

Lo más importante es el segundo paso: ponemos el código de Ajax-hook, axios y proxy en un archivo hook.js y lo ejecutamos con el execute_script de Selenium.

Los otros pasos son muy simples y la implementación final es la siguiente:

from selenium import webdriver
import time

browser = webdriver.Chrome()
browser.get('https://dynamic2.scrape.center/')
browser.execute_script(open('hook.js').read())
time.sleep(2)

for index in range(10):
    print('current page', index)
    btn_next = browser.find_element_by_css_selector('.btn-next')
    btn_next.click()
    time.sleep(2)

Finalmente, ejecútelo.

Se puede encontrar que el navegador primero abrió la página, luego simuló hacer clic en la página siguiente, y luego regresó para observar el lado del Flask Server, puede ver que se reciben los datos Ajax, como se muestra en la figura:

Vale eso es todo.

para resumir

En este punto, hemos completado:

  • Gancho de respuesta Ajax
  • Reenvío y recepción de datos
  • Automatización del navegador

Cuando nos encontremos con situaciones similares en el futuro, podemos tratarlas de la misma manera.

Código para esta sección: https://github.com/Python3WebSpider/AjaxHookSpider.

Supongo que te gusta

Origin blog.csdn.net/zhangge3663/article/details/108658819
Recomendado
Clasificación