Finalmente chegou às partes mais difíceis do curso, onde o objetivo é automatizar os logins dos bots em todos os bots disponíveis.

Os tópicos desta secção incluem o seguinte:

  1. Como tudo se encaixa
  2. Login automatizado e contornar captcha
  3. Modelos de base de dados para perfis de bots
  4. Rotas de backend
  5. Modelo de frontend
  6. Testes

Como tudo se encaixa

Aqui está uma visão geral de alto nível de como todos os componentes em tornet_scraper se integram:

  1. Na Secção 3.1, você configurou o seu ambiente de desenvolvimento para começar.
  2. Na Secção 3.2, aprendeu a gerar proxies para ligações seguras.
  3. Na Secção 3.3, explorou a criação de APIs para ignorar CAPTCHA, identificar Initial Access Brokers (IABs) e traduzir dados.

Estas são competências impressionantes. Agora, vamos abordar como estes elementos se combinam para gerir perfis de bot. Eis como as funcionalidades funcionam em conjunto:

  1. Geração de proxy: utilizará o gerador de proxy para criar proxies Tor, que os perfis de bot precisam para aceder ao site Tor com segurança.
  2. Gestão de API: utilizará a gestão de API para adicionar uma API CAPTCHA, permitindo que os bots contornem CAPTCHAs e iniciem sessão com sucesso.
  3. Gestão de bots:
    1. Use a interface para criar bots inserindo o nome de utilizador, a palavra-passe, a finalidade e o proxy atribuído.
    2. Especifique o URL de login para os bots.
    3. Clique em “Perform Bot Login” para iniciar sessão em todas as contas de bot e contornar CAPTCHAs automaticamente.
  4. Após o login, o sistema atualiza uma tabela para mostrar quais contas têm sessões ativas.

Se executar «Perform Bot Login» duas vezes para todas as contas, o backend irá buscar novas sessões. O facto de uma sessão estar marcada como ativa não garante que seja válida. É altamente recomendável executar o login do bot sempre que iniciar a aplicação para garantir sessões ativas e funcionais.


Login automatizado e contornar captchas

Este tópico não deve intimidar ninguém, não é magia. Nas seções anteriores, exploramos como ignorar CAPTCHAs usando o modelo ChatGPT o3, mas como a API OpenAI para o3 não suporta imagens, agora usaremos o modelo gpt-4.1, que se provou eficaz para ignorar CAPTCHAs na minha experiência.

Lembre-se sempre de que muitos modelos de IA proíbem a ignorar CAPTCHAs para fins maliciosos, pois isso viola os seus termos de serviço e pode ser ilegal. Neste curso, estamos a utilizar esses modelos em um ambiente controlado para fins educacionais, garantindo a conformidade com as normas legais. Não endosso nem tolero atividades ilegais com modelos de IA.

Na plataforma OpenAI, o Playground permite que experimente vários modelos. Recomendo experimentá-lo antes de prosseguir, pois modelos mais recentes podem estar disponíveis quando ler isto. Com os modelos de IA a evoluir mensalmente, pode existir um modelo mais avançado para OCR quando abordar esta secção.

O processo de contornar o CAPTCHA é simples:

  1. Abra a página de login
  2. Baixe a imagem do CAPTCHA
  3. Redimensione-a para melhorar a legibilidade
  4. Codifique a imagem como base64 e envie-a para o modelo de IA com um prompt
  5. Recupere o texto do CAPTCHA extraído
  6. Use o texto do CAPTCHA, nome de utilizador e palavra-passe para fazer login
  7. Obtenha a sessão após um login bem-sucedido
  8. Use a sessão para extrair informações de mercados, publicações e perfis

Embora isso possa parecer complexo, dividir em funções individuais facilita a compreensão de como tudo se conecta.

O código para realizar o login com o CAPTCHA bypass está localizado em app/services/tornet_forum_login.py.

Funções

  1. image_to_base64:

    • Objetivo: Converte um ficheiro de imagem numa string codificada em base64 para envio à API.
    • Parâmetros principais:
      • image_path: Caminho para o ficheiro de imagem.
    • Retorna: String Base64 ou None em caso de erro.
    • Detalhes: Lê o ficheiro de imagem em modo binário, codifica-o para base64 e regista o processo. Retorna None se o acesso ao ficheiro ou a codificação falhar.
  2. resize_image:

    • Objetivo: Redimensiona uma imagem para as dimensões especificadas para um processamento CAPTCHA consistente.
    • Parâmetros principais:
      • image_path: Caminho para a imagem de entrada.
      • output_path: Caminho para salvar a imagem redimensionada.
      • size: Tupla das dimensões desejadas (padrão: 354x112).
    • Retorna: True em caso de sucesso, False em caso de erro.
    • Detalhes: Utiliza PIL para redimensionar a imagem com reamostragem LANCZOS, guarda-a como PNG e regista a operação. Retorna False se o redimensionamento ou o armazenamento falharem.
  3. clean_captcha_text:

    • Objetivo: Extraia um código CAPTCHA de 6 caracteres (letras maiúsculas e números) do texto bruto.
    • Parâmetros principais:
      • captcha_text: Texto de saída da API OpenAI.
    • Retorna: Código de 6 caracteres ou None se a extração falhar.
    • Detalhes: Usa regex ([A-Z0-9]{6}) para encontrar o código, registra o resultado limpo e retorna None se nenhuma correspondência for encontrada ou se ocorrer um erro.
  4. solve_captcha:

    • Objetivo: Resolve uma imagem CAPTCHA usando a API OpenAI.
    • Parâmetros principais:
      • image_path: Caminho para a imagem CAPTCHA.
      • api_key: Chave da API OpenAI.
      • model_name: Modelo OpenAI (por exemplo, GPT-4).
      • max_tokens: Número máximo de tokens para a resposta da API.
      • prompt: Texto de instruções para a API.
    • Retorna: Código CAPTCHA de 6 caracteres limpo ou None em caso de erro.
    • Detalhes:
      • Redimensiona a imagem CAPTCHA para um tamanho fixo usando resize_image.
      • Converte a imagem redimensionada para base64 usando image_to_base64.
      • Envia a imagem base64 e o prompt para a API OpenAI através de client.chat.completions.create, solicitando o texto CAPTCHA.
      • Limpa a resposta da API usando clean_captcha_text e retorna o resultado. Regista erros e retorna None em caso de falha.
  5. login_to_tor_website:

    • Objetivo: Efetua o login num site Tor resolvendo CAPTCHAs e enviando credenciais de login, retornando uma sessão com cookies.
    • Parâmetros-chave:
      • api_key: Chave API OpenAI para resolução de CAPTCHA.
      • max_tokens: Número máximo de tokens para a API OpenAI.
      • model_name: nome do modelo OpenAI.
      • login_url: URL da página de login.
      • username: nome de utilizador de login.
      • password: palavra-passe de login.
      • tor_proxy: URL do proxy Tor (por exemplo, socks5h://127.0.0.1:9050).
      • prompt: solicitação para resolver o CAPTCHA OpenAI.
      • timeout: Tempo limite da solicitação (padrão: 20 segundos).
    • Retorna: requests.Session com cookies em caso de sucesso, None em caso de falha.
    • Detalhes:
      • Cria um requests.Session com o proxy Tor e um agente de utilizador aleatório (de gen_desktop_ua).
      • Tenta o login até 9 vezes, com uma espera de 5 minutos após o número máximo de tentativas.
      • Busca a página de login, extrai a URL da imagem CAPTCHA usando BeautifulSoup e faz o download.
      • Resolve o CAPTCHA usando solve_captcha.
      • Envia os dados de login (nome de utilizador, palavra-passe, código CAPTCHA e quaisquer campos ocultos do formulário, como tokens CSRF) via POST.
      • Verifica a resposta para ver se foi bem-sucedida (“profile” e “logout” no texto), credenciais inválidas ou CAPTCHA inválido. Tenta novamente em caso de falhas, limpa os ficheiros temporários (imagens CAPTCHA) e retorna a sessão com cookies em caso de sucesso.

O script tenta o login até 9 vezes antes de pausar por 5 minutos e tentar novamente. A resolução do CAPTCHA pode ser imprevisível, com alguns CAPTCHAs sendo mais fáceis de resolver do que outros. A estratégia é persistir com as tentativas até que o login seja bem-sucedido. Normalmente, o sucesso ocorre dentro de 5 tentativas, com base na minha experiência.


Modelos de base de dados para perfis de bots

Os modelos de base de dados para perfis de bots incluem todos os detalhes necessários, tais como a finalidade do bot, o URL tornet_forum e as contas do bot, mas estes estão organizados em modelos separados para uma melhor gestão e clareza.

Os seus modelos estão localizados em app/database/models.py. Aqui estão eles:

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 a tarefa principal de um bot, suportando três tipos de scraping:

  1. Scraping de links de publicações do marketplace (excluindo conteúdo).
  2. Scraping de publicações com os seus links.
  3. Scraping de links de publicações dos perfis dos utilizadores.

Isto requer tipos de bots distintos para cada finalidade.


Rotas de backend

O módulo tornet_forum_login.py lida com a funcionalidade principal de login, portanto, não são necessárias interações exclusivas para ele. A interface do perfil do bot requer as seguintes funcionalidades principais:

  1. Listar bots existentes.
  2. Criar novos bots.
  3. Atualizar detalhes do bot.
  4. Eliminar bots.
  5. Criar e modificar URLs onion.
  6. Efetuar o login.

Estas estão alinhadas com as operações CRUD discutidas anteriormente. A funcionalidade de login depende da função login_to_tor_website, pelo que não são introduzidos novos conceitos para além do CRUD padrão.

O seu código está localizado em app/routes/bot_profile.py.

Funções

  1. get_bot_profiles:

    • Objetivo: Recupera todos os perfis de bot da base de dados.
    • Parâmetros principais:
      • db: SQLAlchemy Session (via Depends(get_db)).
    • Retorna: Lista de dicionários com detalhes do perfil (ID, nome de utilizador, palavra-passe mascarada, finalidade, proxy Tor, estado da sessão, agente do utilizador, carimbo de data/hora).
    • Detalhes: Consulta a tabela BotProfile, mascara a palavra-passe por motivos de segurança e devolve os dados do perfil. Apresenta uma HTTPException (500) em caso de erro.
  2. create_bot_profile:

    • Finalidade: Cria um novo perfil de bot.
    • Parâmetros-chave:
      • profile: BotProfileCreate com dados do perfil.
      • request: FastAPI Request para mensagens flash baseadas em sessão.
      • db: SQLAlchemy Session.
    • Retorna: Dicionário com mensagem de sucesso e mensagem flash.
    • Detalhes: Verifica se há nomes de utilizador duplicados, cria uma instância BotProfile com um agente de utilizador aleatório (de gen_desktop_ua), guarda-a na base de dados e adiciona uma mensagem flash de sucesso à sessão. Levanta HTTPException (400 para duplicados, 500 para erros) com reversão em caso de falha.
  3. update_bot_profile:

    • Objetivo: Atualiza um perfil de bot existente.
    • Parâmetros principais:
      • profile_id: ID inteiro do perfil.
      • profile: BotProfileUpdate com campos atualizados.
      • request: FastAPI Request para mensagens flash.
      • db: SQLAlchemy Session.
    • Retorna: Dicionário com mensagem de sucesso e mensagem flash.
    • Detalhes: Verifica se o perfil existe, verifica se há nomes de utilizador duplicados (se alterados), atualiza campos que não sejam None (incluindo BotPurpose enum) e confirma as alterações. Adiciona uma mensagem flash de sucesso. Levanta HTTPException (404 se não encontrado, 400 para duplicados, 500 para erros) com reversão em caso de falha.
  4. delete_bot_profile:

    • Objetivo: Elimina um perfil de bot.
    • Parâmetros-chave:
      • profile_id: ID inteiro do perfil.
      • request: FastAPI Request para mensagens flash.
      • db: SQLAlchemy Session.
    • Retorna: Dicionário com mensagem de sucesso e mensagem flash.
    • Detalhes: Verifica se o perfil existe, elimina-o da tabela BotProfile e adiciona uma mensagem flash de sucesso. Levanta HTTPException (404 se não for encontrado, 500 para erros) com reversão em caso de falha.
  5. get_onion_url:

    • Objetivo: Recupera o URL onion mais recente.
    • Parâmetros-chave:
      • db: SQLAlchemy Session.
    • Retorna: Dicionário com o último OnionUrl.url ou None.
    • Detalhes: Consulta a tabela OnionUrl, ordenada por data e hora (descendente), e retorna a URL mais recente. Gera HTTPException (500) em caso de erros.
  6. set_onion_url:

    • Objetivo: Cria uma nova entrada de URL onion.
    • Parâmetros-chave:
      • onion: OnionUrlCreate com a URL.
      • request: FastAPI Request para mensagens flash.
      • db: SQLAlchemy Session.
    • Retorna: Dicionário com mensagem de sucesso e mensagem flash.
    • Detalhes: Cria uma instância OnionUrl, guarda-a na base de dados e adiciona uma mensagem flash de sucesso. Levanta HTTPException (500) com reversão em caso de falha.
  7. perform_bot_login:

    • Objetivo: Automatiza o login para todos os perfis de bot usando uma API CAPTCHA.
    • Parâmetros principais:
      • request: FastAPI Request para mensagens flash.
      • db: SQLAlchemy Session.
    • Retorna: Dicionário com resultados de login e mensagem flash.
    • Detalhes:
      • Busca o OnionUrl mais recente e o captcha_api ativo da tabela APIs.
      • Consulta todas as entradas BotProfile e tenta fazer login em cada uma usando login_to_tor_website (de tornet_forum_login.py) com parâmetros da API CAPTCHA.
      • Se um cookie de sessão for recebido, formata-o como session=<value>, atualiza o campo session do perfil e incrementa a contagem de sucesso. Logins com falha são registrados e coletados.
      • Retorna uma mensagem resumida com a contagem de sucesso e logins falhados, adicionando uma mensagem flash (sucesso se algum login for bem-sucedido, erro caso contrário). Levanta HTTPException (400 para URL/API/perfis ausentes, 500 para erros) com reversão em caso de falha.

Modelo front-end

O código do seu modelo está localizado em app/templates/bot_profile.html.

O modelo bot_profile.html fornece uma interface de utilizador para gerir perfis de bots e URLs onion na aplicação tornet_scraper, interagindo com o back-end através de chamadas API para realizar operações CRUD em perfis de bots, definir URLs onion e automatizar inícios de sessão. Abaixo está uma explicação concisa das suas principais funcionalidades e interações com o backend.

  1. Gestão de URLs onion:

    • Objetivo: permite aos utilizadores definir e exibir a URL .onion para acesso ao site Tor.
    • Interação com o backend:
      • Um campo de entrada e o botão “Atualizar URL .onion” acionam setOnionUrl(), enviando uma solicitação AJAX POST para /api/bot-profile/onion-url (tratada por bot_profile.py::set_onion_url) com a URL inserida.
      • O backend guarda o URL na tabela OnionUrl, adiciona uma mensagem flash de sucesso à sessão e retorna uma resposta de sucesso. Em caso de sucesso, a página é recarregada e loadOnionUrl() obtém o URL mais recente através de uma solicitação GET para /api/bot-profile/onion-url, atualizando a exibição. Erros acionam uma mensagem flash de erro.
  2. Criação do perfil do bot:

    • Objetivo: permite adicionar novos perfis de bot.
    • Interação com o backend:
      • O botão “Adicionar bot” abre um modal com campos para nome de utilizador, palavra-passe, objetivo (menu suspenso: scrape_marketplace, scrape_post, scrape_profile), proxy Tor e sessão (opcional).
      • A função createBotProfile() envia uma solicitação AJAX POST para /api/bot-profile/create (tratada por bot_profile.py::create_bot_profile) com os dados do formulário.
      • O backend valida o nome de utilizador, cria um BotProfile com um agente de utilizador aleatório, guarda-o na base de dados e adiciona uma mensagem flash de sucesso. Se for bem-sucedido, o modal fecha e a página é recarregada. Erros (por exemplo, nome de utilizador duplicado) acionam uma mensagem flash de erro.
  3. Lista e atualizações do perfil do bot:

    • Objetivo: Exibe e atualiza uma tabela de perfis de bots.
    • Interação com o backend:
      • A função loadBotProfiles(), acionada ao carregar a página e pelo botão “Atualizar”, envia uma solicitação AJAX GET para /api/bot-profile/list (tratada por bot_profile.py::get_bot_profiles).
      • O backend retorna uma lista de perfis (ID, nome de utilizador, palavra-passe mascarada, finalidade, proxy Tor, estado da sessão, agente do utilizador, carimbo de data/hora), preenchendo a tabela. Os erros acionam uma mensagem de erro instantânea.
      • A tabela é atualizada automaticamente após ações de criação, atualização ou eliminação.
  4. Edição do perfil do bot:

    • Objetivo: Permite atualizar perfis de bots existentes.
    • Interação com o backend:
      • O botão «Editar» de cada linha da tabela chama openEditModal(), preenchendo um modal com os dados do perfil.
      • A função updateBotProfile() envia uma solicitação AJAX PUT para /api/bot-profile/{profile_id} (tratada por bot_profile.py::update_bot_profile) com os campos atualizados (nome de utilizador, palavra-passe, finalidade, proxy Tor, agente do utilizador, sessão; os campos opcionais podem permanecer inalterados).
      • O backend valida e atualiza o BotProfile, adicionando uma mensagem flash de sucesso. Em caso de sucesso, o modal fecha e a página é recarregada. Erros (por exemplo, nome de utilizador duplicado) acionam uma mensagem flash de erro.
  5. Eliminação do perfil do bot:

    • Objetivo: Elimina um perfil de bot.
    • Interação do backend:
      • O botão «Eliminar» de cada linha da tabela abre um modal de confirmação através de openDeleteModal(), armazenando o ID do perfil.
      • A função deleteBotProfile() envia um pedido AJAX DELETE para /api/bot-profile/{profile_id} (tratado por bot_profile.py::delete_bot_profile).
      • O backend elimina o perfil da tabela BotProfile e adiciona uma mensagem flash de sucesso. Se for bem-sucedido, o modal fecha e a página é recarregada. Os erros acionam uma mensagem flash de erro.
  6. Login automatizado do bot:

    • Objetivo: Aciona o login para todos os perfis de bot usando a resolução de CAPTCHA.
    • Interação do backend:
      • O botão «Perform Bot Login» chama performBotLogin(), enviando uma solicitação AJAX POST para /api/bot-profile/perform-login.
      • O backend busca o URL onion mais recente, a API CAPTCHA ativa e todos os perfis, depois usa login_to_tor_website para autenticar cada perfil, armazenando cookies de sessão na tabela BotProfile. Ele retorna um resumo dos logins bem-sucedidos e com falha com uma mensagem instantânea (sucesso se algum login for bem-sucedido, erro caso contrário).
      • Em caso de sucesso ou erro, a página é recarregada e mensagens instantâneas exibem o resultado.

Testes

Para testar esta funcionalidade, primeiro é necessário adicionar uma API Captcha. Recomendo obter uma chave API gpt-4.1 e adicioná-la através da página API Management.

Para o prompt, pode usar isto:

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.

Depois de tudo concluído, deverá conseguir iniciar sessão numa ou várias contas e as respetivas sessões serão atualizadas. Se a sessão estiver definida como verdadeira, provavelmente foi preenchida.

IU de gestão de perfis de bot