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:
- Como tudo se encaixa
- Login automatizado e contornar captcha
- Modelos de base de dados para perfis de bots
- Rotas de backend
- Modelo de frontend
- 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:
- Na Secção 3.1, você configurou o seu ambiente de desenvolvimento para começar.
- Na Secção 3.2, aprendeu a gerar proxies para ligações seguras.
- 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:
- 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.
- 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.
- Gestão de bots:
- Use a interface para criar bots inserindo o nome de utilizador, a palavra-passe, a finalidade e o proxy atribuído.
- Especifique o URL de login para os bots.
- Clique em “Perform Bot Login” para iniciar sessão em todas as contas de bot e contornar CAPTCHAs automaticamente.
- 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:
- Abra a página de login
- Baixe a imagem do CAPTCHA
- Redimensione-a para melhorar a legibilidade
- Codifique a imagem como base64 e envie-a para o modelo de IA com um prompt
- Recupere o texto do CAPTCHA extraído
- Use o texto do CAPTCHA, nome de utilizador e palavra-passe para fazer login
- Obtenha a sessão após um login bem-sucedido
- 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
-
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
Noneem caso de erro. - Detalhes: Lê o ficheiro de imagem em modo binário, codifica-o para base64 e regista o processo. Retorna
Nonese o acesso ao ficheiro ou a codificação falhar.
-
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:
Trueem caso de sucesso,Falseem caso de erro. - Detalhes: Utiliza PIL para redimensionar a imagem com reamostragem LANCZOS, guarda-a como PNG e regista a operação. Retorna
Falsese o redimensionamento ou o armazenamento falharem.
-
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
Nonese a extração falhar. - Detalhes: Usa regex (
[A-Z0-9]{6}) para encontrar o código, registra o resultado limpo e retornaNonese nenhuma correspondência for encontrada ou se ocorrer um erro.
-
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
Noneem 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_texte retorna o resultado. Regista erros e retornaNoneem caso de falha.
- Redimensiona a imagem CAPTCHA para um tamanho fixo usando
-
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.Sessioncom cookies em caso de sucesso,Noneem caso de falha. - Detalhes:
- Cria um
requests.Sessioncom o proxy Tor e um agente de utilizador aleatório (degen_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.
- Cria um
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:
- Scraping de links de publicações do marketplace (excluindo conteúdo).
- Scraping de publicações com os seus links.
- 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:
- Listar bots existentes.
- Criar novos bots.
- Atualizar detalhes do bot.
- Eliminar bots.
- Criar e modificar URLs onion.
- 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
-
get_bot_profiles:- Objetivo: Recupera todos os perfis de bot da base de dados.
- Parâmetros principais:
db: SQLAlchemySession(viaDepends(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 umaHTTPException(500) em caso de erro.
-
create_bot_profile:- Finalidade: Cria um novo perfil de bot.
- Parâmetros-chave:
profile:BotProfileCreatecom dados do perfil.request: FastAPIRequestpara mensagens flash baseadas em sessão.db: SQLAlchemySession.
- Retorna: Dicionário com mensagem de sucesso e mensagem flash.
- Detalhes: Verifica se há nomes de utilizador duplicados, cria uma instância
BotProfilecom um agente de utilizador aleatório (degen_desktop_ua), guarda-a na base de dados e adiciona uma mensagem flash de sucesso à sessão. LevantaHTTPException(400 para duplicados, 500 para erros) com reversão em caso de falha.
-
update_bot_profile:- Objetivo: Atualiza um perfil de bot existente.
- Parâmetros principais:
profile_id: ID inteiro do perfil.profile:BotProfileUpdatecom campos atualizados.request: FastAPIRequestpara mensagens flash.db: SQLAlchemySession.
- 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(incluindoBotPurposeenum) e confirma as alterações. Adiciona uma mensagem flash de sucesso. LevantaHTTPException(404 se não encontrado, 400 para duplicados, 500 para erros) com reversão em caso de falha.
-
delete_bot_profile:- Objetivo: Elimina um perfil de bot.
- Parâmetros-chave:
profile_id: ID inteiro do perfil.request: FastAPIRequestpara mensagens flash.db: SQLAlchemySession.
- Retorna: Dicionário com mensagem de sucesso e mensagem flash.
- Detalhes: Verifica se o perfil existe, elimina-o da tabela
BotProfilee adiciona uma mensagem flash de sucesso. LevantaHTTPException(404 se não for encontrado, 500 para erros) com reversão em caso de falha.
-
get_onion_url:- Objetivo: Recupera o URL onion mais recente.
- Parâmetros-chave:
db: SQLAlchemySession.
- Retorna: Dicionário com o último
OnionUrl.urlouNone. - Detalhes: Consulta a tabela
OnionUrl, ordenada por data e hora (descendente), e retorna a URL mais recente. GeraHTTPException(500) em caso de erros.
-
set_onion_url:- Objetivo: Cria uma nova entrada de URL onion.
- Parâmetros-chave:
onion:OnionUrlCreatecom a URL.request: FastAPIRequestpara mensagens flash.db: SQLAlchemySession.
- 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. LevantaHTTPException(500) com reversão em caso de falha.
-
perform_bot_login:- Objetivo: Automatiza o login para todos os perfis de bot usando uma API CAPTCHA.
- Parâmetros principais:
request: FastAPIRequestpara mensagens flash.db: SQLAlchemySession.
- Retorna: Dicionário com resultados de login e mensagem flash.
- Detalhes:
- Busca o
OnionUrlmais recente e ocaptcha_apiativo da tabelaAPIs. - Consulta todas as entradas
BotProfilee tenta fazer login em cada uma usandologin_to_tor_website(detornet_forum_login.py) com parâmetros da API CAPTCHA. - Se um cookie de sessão for recebido, formata-o como
session=<value>, atualiza o camposessiondo 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.
- Busca o
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.
-
Gestão de URLs onion:
- Objetivo: permite aos utilizadores definir e exibir a URL
.onionpara 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 porbot_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 eloadOnionUrl()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.
- Um campo de entrada e o botão “Atualizar URL .onion” acionam
- Objetivo: permite aos utilizadores definir e exibir a URL
-
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 porbot_profile.py::create_bot_profile) com os dados do formulário. - O backend valida o nome de utilizador, cria um
BotProfilecom 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.
- O botão “Adicionar bot” abre um modal com campos para nome de utilizador, palavra-passe, objetivo (menu suspenso:
-
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 porbot_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.
- A função
-
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 porbot_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.
- O botão «Editar» de cada linha da tabela chama
-
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 porbot_profile.py::delete_bot_profile). - O backend elimina o perfil da tabela
BotProfilee 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.
- O botão «Eliminar» de cada linha da tabela abre um modal de confirmação através de
-
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_websitepara autenticar cada perfil, armazenando cookies de sessão na tabelaBotProfile. 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.
- O botão «Perform Bot Login» chama
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.
