Por fin has llegado a las partes más difíciles del curso, donde el objetivo es automatizar los inicios de sesión de todos los bots disponibles.
Los temas de esta sección incluyen lo siguiente:
- Cómo se integra todo
- Inicio de sesión automatizado y omisión de captcha
- Modelos de base de datos para perfiles de bots
- Rutas de backend
- Plantilla de frontend
- Pruebas
Cómo se integra todo
A continuación se ofrece una descripción general de alto nivel de cómo se integran todos los componentes de tornet_scraper:
- En la sección 3.1, configuraste tu entorno de desarrollo para empezar.
- En la sección 3.2, aprendiste a generar proxies para conexiones seguras.
- En la sección 3.3, exploraste la creación de API para eludir CAPTCHA, identificar los Initial Access Brokers (IAB) y traducir datos.
Son habilidades impresionantes. Ahora veremos cómo se combinan estos elementos para gestionar los perfiles de los bots. Así es como funcionan las funcionalidades en conjunto:
- Generación de proxies: utilizará el generador de proxies para crear proxies Tor, que los perfiles de bots necesitan para acceder de forma segura al sitio Tor.
- Gestión de API: aprovechará la gestión de API para añadir una API CAPTCHA, lo que permitirá a los bots eludir los CAPTCHA e iniciar sesión correctamente.
- Gestión de bots:
- Utilice la interfaz para crear bots introduciendo su nombre de usuario, contraseña, finalidad y proxy asignado.
- Especifique la URL de inicio de sesión de los bots.
- Haga clic en «Realizar inicio de sesión del bot» para iniciar sesión en todas las cuentas de bot y evitar los CAPTCHA automáticamente.
- Después de iniciar sesión, el sistema actualiza una tabla para mostrar qué cuentas tienen sesiones activas.
Si ejecuta «Realizar inicio de sesión del bot» dos veces para todas las cuentas, el backend obtendrá nuevas sesiones. El hecho de que una sesión esté marcada como activa no garantiza que sea válida. Se recomienda encarecidamente realizar el inicio de sesión del bot cada vez que inicie la aplicación para garantizar que las sesiones estén activas y funcionen.
Inicio de sesión automatizado y omisión de captchas
Este tema no debería intimidar a nadie, no es magia. En secciones anteriores, exploramos cómo evitar los CAPTCHA utilizando el modelo ChatGPT o3, pero dado que la API de OpenAI para o3 no admite imágenes, ahora utilizaremos el modelo gpt-4.1, que ha demostrado ser eficaz para evitar los CAPTCHA según mi experiencia.
Recuerda siempre que muchos modelos de IA prohíben evitar los CAPTCHA con fines maliciosos, ya que viola sus condiciones de servicio y puede ser ilegal. En este curso, utilizamos estos modelos en un entorno controlado con fines educativos, garantizando el cumplimiento de las normas legales. No apruebo ni condono las actividades ilegales con modelos de IA.
En la plataforma OpenAI, el Playground te permite experimentar con varios modelos. Te recomiendo que lo pruebes antes de continuar, ya que es posible que haya modelos más nuevos disponibles cuando leas esto. Dado que los modelos de IA evolucionan cada mes, es posible que exista un modelo más avanzado para OCR cuando llegues a esta sección.
El proceso para saltarse el CAPTCHA es sencillo:
- Abre la página de inicio de sesión.
- Descarga la imagen del CAPTCHA.
- Cambia el tamaño para mejorar la legibilidad.
- Codifica la imagen como base64 y envíala al modelo de IA con un mensaje.
- Recupera el texto del CAPTCHA extraído.
- Utiliza el texto del CAPTCHA, el nombre de usuario y la contraseña para iniciar sesión.
- Obtener la sesión tras iniciar sesión correctamente
- Utilizar la sesión para extraer datos de mercados, publicaciones y perfiles
Aunque pueda parecer complejo, si lo desglosamos en funciones individuales, es fácil comprender cómo se conecta todo.
El código para iniciar sesión sin CAPTCHA se encuentra en app/services/tornet_forum_login.py.
Funciones
-
image_to_base64:- Propósito: Convierte un archivo de imagen en una cadena codificada en base64 para su envío a la API.
- Parámetros clave:
image_path: Ruta al archivo de imagen.
- Devuelve: Cadena Base64 o
Noneen caso de error. - Detalles: Lee el archivo de imagen en modo binario, lo codifica en base64 y registra el proceso. Devuelve
Nonesi falla el acceso al archivo o la codificación.
-
resize_image:- Propósito: Cambia el tamaño de una imagen a las dimensiones especificadas para un procesamiento CAPTCHA coherente.
- Parámetros clave:
image_path: Ruta a la imagen de entrada.output_path: Ruta para guardar la imagen redimensionada.size: Tupla de dimensiones de destino (por defecto: 354x112).
- Devuelve:
Truesi se realiza correctamente,Falsesi se produce un error. - Detalles: Utiliza PIL para cambiar el tamaño de la imagen con remuestreo LANCZOS, la guarda como PNG y registra la operación. Devuelve
Falsesi falla el cambio de tamaño o el guardado.
-
clean_captcha_text:- Propósito: Extrae un código CAPTCHA de 6 caracteres (letras mayúsculas y números) del texto sin formato.
- Parámetros clave:
captcha_text: Texto generado por la API de OpenAI.
- Devuelve: Código de 6 caracteres o
Nonesi falla la extracción. - Detalles: Utiliza una expresión regular (
[A-Z0-9]{6}) para encontrar el código, registra el resultado limpio y devuelveNonesi no se encuentra ninguna coincidencia o se produce un error.
-
solve_captcha:- Finalidad: Resuelve una imagen CAPTCHA utilizando la API de OpenAI.
- Parámetros clave:
image_path: Ruta a la imagen CAPTCHA.api_key: Clave API de OpenAI.model_name: Modelo OpenAI (por ejemplo, GPT-4).max_tokens: Número máximo de tokens para la respuesta de la API.prompt: Texto de instrucciones para la API.
- Devuelve: Código CAPTCHA de 6 caracteres limpio o
Nonesi se produce un error. - Detalles:
- Cambia el tamaño de la imagen CAPTCHA a un tamaño fijo utilizando
resize_image. - Convierte la imagen redimensionada a base64 utilizando
image_to_base64. - Envía la imagen base64 y el mensaje a la API de OpenAI a través de
client.chat.completions.create, solicitando el texto del CAPTCHA. - Limpia la respuesta de la API utilizando
clean_captcha_texty devuelve el resultado. Registra los errores y devuelveNoneen caso de fallo.
- Cambia el tamaño de la imagen CAPTCHA a un tamaño fijo utilizando
-
login_to_tor_website:- Propósito: inicia sesión en un sitio web Tor resolviendo CAPTCHAs y enviando las credenciales de inicio de sesión, devolviendo una sesión con cookies.
- Parámetros clave:
api_key: clave API de OpenAI para resolver CAPTCHAs.max_tokens: número máximo de tokens para la API de OpenAI.model_name: nombre del modelo OpenAI.login_url: URL de la página de inicio de sesión.username: nombre de usuario de inicio de sesión.password: contraseña de inicio de sesión.tor_proxy: URL del proxy Tor (por ejemplo,socks5h://127.0.0.1:9050).prompt: solicitud para resolver el CAPTCHA de OpenAI.timeout: tiempo de espera de la solicitud (por defecto: 20 segundos).
- Devuelve:
requests.Sessioncon cookies si se realiza correctamente,Nonesi falla. - Detalles:
- Crea una
requests.Sessioncon el proxy Tor y un agente de usuario aleatorio (degen_desktop_ua). - Intenta iniciar sesión hasta 9 veces, con una espera de 5 minutos después del máximo de intentos.
- Obtiene la página de inicio de sesión, extrae la URL de la imagen CAPTCHA utilizando BeautifulSoup y la descarga.
- Resuelve el CAPTCHA utilizando
solve_captcha. - Envía los datos de inicio de sesión (nombre de usuario, contraseña, código CAPTCHA y cualquier campo oculto del formulario, como tokens CSRF) mediante POST.
- Comprueba la respuesta para ver si ha tenido éxito (
«profile» y «logout»en el texto), si las credenciales son inválidas o si el CAPTCHA es inválido. Vuelve a intentarlo en caso de fallo, limpia los archivos temporales (imágenes CAPTCHA) y devuelve la sesión con las cookies en caso de éxito.
- Crea una
El script intenta iniciar sesión hasta 9 veces antes de pausarse durante 5 minutos y volver a intentarlo. La resolución del CAPTCHA puede ser impredecible, ya que algunos CAPTCHA son más fáciles de resolver que otros. La estrategia consiste en persistir con los reintentos hasta que se logre iniciar sesión correctamente. Por lo general, según mi experiencia, el éxito se produce en 5 intentos.
Modelos de base de datos para perfiles de bots
Los modelos de base de datos para perfiles de bots incluyen todos los detalles necesarios, como el propósito del bot, la URL de tornet_forum y las cuentas de bot, pero están organizados en modelos separados para una mejor gestión y claridad.
Tus modelos se encuentran en app/database/models.py. Aquí están:
class BotPurpose(enum.Enum):
SCRAPE_MARKETPLACE = "scrape_marketplace"
SCRAPE_POST = "scrape_post"
SCRAPE_PROFILE = "scrape_profile"
class BotProfile(Base):
__tablename__ = "bot_profiles"
id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True, nullable=False)
password = Column(String, nullable=False)
purpose = Column(Enum(BotPurpose), nullable=False)
tor_proxy = Column(String, nullable=True)
user_agent = Column(String, nullable=True)
session = Column(Text)
timestamp = Column(DateTime, default=datetime.utcnow)
BotPurpose define la tarea principal de un bot y admite tres tipos de scraping:
- Scraping de enlaces de publicaciones del mercado (excluyendo el contenido).
- Scraping de publicaciones con sus enlaces.
- Scraping de enlaces de publicaciones de perfiles de usuario.
Esto requiere tipos de bots distintos para cada propósito.
Rutas de backend
El módulo tornet_forum_login.py se encarga de la funcionalidad básica de inicio de sesión, por lo que no se necesitan interacciones únicas para ello. La interfaz del perfil del bot requiere las siguientes funcionalidades clave:
- Listar los bots existentes.
- Crear nuevos bots.
- Actualizar los detalles del bot.
- Eliminar bots.
- Crear y modificar URL onion.
- Iniciar sesión.
Estas se alinean con las operaciones CRUD discutidas anteriormente. La funcionalidad de inicio de sesión se basa en la función login_to_tor_website, por lo que no se introducen nuevos conceptos más allá del CRUD estándar.
Tu código se encuentra en app/routes/bot_profile.py.
Funciones
-
get_bot_profiles:- Propósito: recupera todos los perfiles de bot de la base de datos.
- Parámetros clave:
db: SQLAlchemySession(a través deDepends(get_db)).
- Devuelve: lista de diccionarios con detalles del perfil (ID, nombre de usuario, contraseña enmascarada, propósito, proxy Tor, estado de la sesión, agente de usuario, marca de tiempo).
- Detalles: Consulta la tabla
BotProfile, enmascara la contraseña por seguridad y devuelve los datos del perfil. Genera una excepciónHTTPException(500) en caso de error.
-
create_bot_profile:- Propósito: Crea un nuevo perfil de bot.
- Parámetros clave:
profile:BotProfileCreatecon datos del perfil.request: FastAPIRequestpara mensajes flash basados en sesiones.db: SQLAlchemySession.
- Devuelve: Diccionario con mensaje de éxito y mensaje flash.
- Detalles: Comprueba si hay nombres de usuario duplicados, crea una instancia
BotProfilecon un agente de usuario aleatorio (degen_desktop_ua), la guarda en la base de datos y añade un mensaje flash de éxito a la sesión. Genera una excepciónHTTPException(400 para duplicados, 500 para errores) con reversión en caso de fallo.
-
update_bot_profile:- Propósito: Actualiza un perfil de bot existente.
- Parámetros clave:
profile_id: ID entero del perfil.profile:BotProfileUpdatecon los campos actualizados.request: FastAPIRequestpara mensajes flash.db: SQLAlchemySession.
- Devuelve: Diccionario con mensaje de éxito y mensaje flash.
- Detalles: verifica que el perfil existe, comprueba si hay nombres de usuario duplicados (si se han cambiado), actualiza los campos que no son
None(incluido el enumeradorBotPurpose) y confirma los cambios. Añade un mensaje flash de éxito. Genera unaHTTPException(404 si no se encuentra, 400 para duplicados, 500 para errores) con reversión en caso de fallo.
-
delete_bot_profile:- Propósito: Elimina un perfil de bot.
- Parámetros clave:
profile_id: ID entero del perfil.request: FastAPIRequestpara mensajes flash.db: SQLAlchemySession.
- Devuelve: Diccionario con mensaje de éxito y mensaje flash.
- Detalles: verifica que el perfil existe, lo elimina de la tabla
BotProfiley añade un mensaje flash de éxito. Genera una excepciónHTTPException(404 si no se encuentra, 500 en caso de error) con reversión en caso de fallo.
-
get_onion_url:- Finalidad: recupera la última URL onion.
- Parámetros clave:
db: SQLAlchemySession.
- Devuelve: Diccionario con la última
OnionUrl.urloNone. - Detalles: Consulta la tabla
OnionUrl, ordenada por marca de tiempo (descendente), y devuelve la URL más reciente. GeneraHTTPException(500) en caso de error.
-
set_onion_url:- Propósito: Crea una nueva entrada de URL onion.
- Parámetros clave:
onion:OnionUrlCreatecon la URL.request: FastAPIRequestpara mensajes flash.db: SQLAlchemySession.
- Devuelve: Diccionario con mensaje de éxito y mensaje flash.
- Detalles: Crea una instancia
OnionUrl, la guarda en la base de datos y añade un mensaje flash de éxito. Genera una excepciónHTTPException(500) con reversión en caso de fallo.
-
perform_bot_login:- Propósito: Automatiza el inicio de sesión para todos los perfiles de bot utilizando una API CAPTCHA.
- Parámetros clave:
request: FastAPIRequestpara mensajes flash.db: SQLAlchemySession.
- Devuelve: Diccionario con los resultados del inicio de sesión y un mensaje flash.
- Detalles:
- Obtiene el último
OnionUrly elcaptcha_apiactivo de la tablaAPIs. - Consulta todas las entradas
BotProfilee intenta iniciar sesión en cada una de ellas utilizandologin_to_tor_website(detornet_forum_login.py) con los parámetros de la API CAPTCHA. - Si se recibe una cookie de sesión, la formatea como
session=<valor>, actualiza el camposessiondel perfil e incrementa el recuento de éxitos. Los inicios de sesión fallidos se registran y recopilan. - Devuelve un mensaje resumen con el recuento de intentos correctos y fallidos, añadiendo un mensaje flash (correcto si alguno de los inicios de sesión ha sido correcto, error en caso contrario). Genera una excepción
HTTPException(400 para URL/API/perfiles que faltan, 500 para errores) con retroceso en caso de fallo.
- Obtiene el último
Plantilla frontend
El código de la plantilla se encuentra en app/templates/bot_profile.html.
La plantilla bot_profile.html proporciona una interfaz de usuario para gestionar los perfiles de los bots y las URL onion en la aplicación tornet_scraper, interactuando con el backend a través de llamadas API para realizar operaciones CRUD en los perfiles de los bots, establecer URL onion y automatizar los inicios de sesión. A continuación se ofrece una explicación concisa de sus funciones principales y de las interacciones con el backend.
-
Gestión de URL onion:
- Propósito: permite a los usuarios establecer y mostrar la URL
.onionpara acceder al sitio web Tor. - Interacción con el backend:
- Un campo de entrada y el botón «Actualizar URL .onion» activan
setOnionUrl(), que envía una solicitud AJAX POST a/api/bot-profile/onion-url(gestionada porbot_profile.py::set_onion_url) con la URL introducida. - El backend guarda la URL en la tabla
OnionUrl, añade un mensaje flash de éxito a la sesión y devuelve una respuesta de éxito. Si se realiza correctamente, la página se recarga yloadOnionUrl()obtiene la última URL mediante una solicitud GET a/api/bot-profile/onion-url, actualizando la visualización. Los errores activan un mensaje flash de error.
- Un campo de entrada y el botón «Actualizar URL .onion» activan
- Propósito: permite a los usuarios establecer y mostrar la URL
-
Creación del perfil del bot:
- Propósito: Permite añadir nuevos perfiles de bot.
- Interacción con el backend:
- El botón «Añadir bot» abre un modal con campos para el nombre de usuario, la contraseña, el propósito (desplegable:
scrape_marketplace,scrape_post,scrape_profile), el proxy Tor y la sesión (opcional). - La función
createBotProfile()envía una solicitud AJAX POST a/api/bot-profile/create(gestionada porbot_profile.py::create_bot_profile) con los datos del formulario. - El backend valida el nombre de usuario, crea un
BotProfilecon un agente de usuario aleatorio, lo guarda en la base de datos y añade un mensaje flash de éxito. Si se realiza correctamente, el modal se cierra y la página se recarga. Los errores (por ejemplo, nombre de usuario duplicado) activan un mensaje flash de error.
- El botón «Añadir bot» abre un modal con campos para el nombre de usuario, la contraseña, el propósito (desplegable:
-
Listado y actualizaciones del perfil del bot:
- Propósito: muestra y actualiza una tabla con los perfiles de los bots.
- Interacción con el backend:
- La función
loadBotProfiles(), activada al cargar la página y al pulsar el botón «Actualizar», envía una solicitud AJAX GET a/api/bot-profile/list(gestionada porbot_profile.py::get_bot_profiles). - El backend devuelve una lista de perfiles (ID, nombre de usuario, contraseña enmascarada, propósito, proxy Tor, estado de la sesión, agente de usuario, marca de tiempo), que se rellena en la tabla. Los errores activan un mensaje de error emergente.
- La tabla se actualiza automáticamente después de las acciones de creación, actualización o eliminación.
- La función
-
Edición del perfil del bot:
- Propósito: Permite actualizar los perfiles de bot existentes.
- Interacción con el backend:
- El botón «Editar» de cada fila de la tabla llama a
openEditModal(), rellenando un modal con los datos del perfil. - La función
updateBotProfile()envía una solicitud AJAX PUT a/api/bot-profile/{profile_id}(gestionada porbot_profile.py::update_bot_profile) con los campos actualizados (nombre de usuario, contraseña, propósito, proxy Tor, agente de usuario, sesión; los campos opcionales pueden permanecer sin cambios). - El backend valida y actualiza el
BotProfile, añadiendo un mensaje flash de éxito. Si se realiza correctamente, el modal se cierra y la página se recarga. Los errores (por ejemplo, nombre de usuario duplicado) activan un mensaje flash de error.
- El botón «Editar» de cada fila de la tabla llama a
-
Eliminación del perfil del bot:
- Propósito: Elimina un perfil de bot.
- Interacción del backend:
- El botón «Eliminar» de cada fila de la tabla abre un modal de confirmación a través de
openDeleteModal(), que almacena el ID del perfil. - La función
deleteBotProfile()envía una solicitud AJAX DELETE a/api/bot-profile/{profile_id}(gestionada porbot_profile.py::delete_bot_profile). - El backend elimina el perfil de la tabla
BotProfiley añade un mensaje flash de éxito. Si se realiza correctamente, el modal se cierra y la página se recarga. Los errores activan un mensaje flash de error.
- El botón «Eliminar» de cada fila de la tabla abre un modal de confirmación a través de
-
Inicio de sesión automático del bot:
- Propósito: Activa el inicio de sesión para todos los perfiles de bot mediante la resolución de CAPTCHA.
- Interacción del backend:
- El botón «Perform Bot Login» llama a
performBotLogin(), enviando una solicitud AJAX POST a/api/bot-profile/perform-login. - El backend obtiene la última URL de cebolla, la API CAPTCHA activa y todos los perfiles, y luego utiliza
login_to_tor_websitepara autenticar cada perfil, almacenando las cookies de sesión en la tablaBotProfile. Devuelve un resumen de los inicios de sesión correctos y fallidos con un mensaje flash (éxito si alguno de los inicios de sesión es correcto, error en caso contrario). - En caso de éxito o error, la página se recarga y se muestran mensajes flash con el resultado.
- El botón «Perform Bot Login» llama a
Pruebas
Para probar esta funcionalidad, primero debes añadir una API Captcha. Te recomiendo obtener una clave API gpt-4.1 y añadirla a través de la página API Management.
Para el prompt, puedes utilizar esto:
The attached image is 6 characters, it contains letters and numbers. The letters are all uppercase. I want you to analyze the image and extract the characters for me, send the combined characters as answer.
Una vez hecho todo esto, deberías poder iniciar sesión en una o varias cuentas y sus sesiones se actualizarán. Si la sesión está establecida en «true», es probable que se haya completado.
