🚀 Ajuda com Automação de Criação de E-mails Reais usando Playwright

Olá, comunidade do TabNews! 👋

Estou desenvolvendo um bot de automação que utiliza o framework Playwright para realizar o processo de criação de e-mails reais. Minha ideia é criar uma solução eficiente e escalável, mas estou enfrentando alguns desafios que têm atrapalhado o progresso.

🛠️ Cenário

A automação segue um fluxo padrão:

  1. Acessar o site do provedor de e-mail.
  2. Preencher as informações do formulário de registro.
  3. Validar as captchas e completar o cadastro.

Apesar de o código estar funcional na maior parte do tempo, ocorrem erros frequentes que interrompem a execução do processo. Esses erros aparecem de forma inconsistente e tornam a automação instável. 🌀

⚠️ Problemas que Enfrento

  • Erro intermitente no fluxo de execução: A automação falha em pontos diferentes sem uma causa aparente.
  • Manuseio de captchas: Apesar de utilizar estratégias para captchas (como serviços de terceiros), a integração ainda não é 100% confiável.
  • Detecção de bot: Alguns provedores parecem identificar que a automação está sendo executada por um bot, retornando erros ou bloqueando o acesso.

🔍 O que já tentei:

  • Ajustes no tempo de espera entre as interações.
  • Implementação de user-agents aleatórios.
  • Melhorias no código para lidar com respostas lentas ou elementos dinâmicos da página.

Mesmo assim, os problemas persistem. 😓

💡 Solicitação de Ajuda

Gostaria de contar com o conhecimento e a experiência de vocês! 🙏
Se você já passou por algo semelhante ou tem ideias sobre como posso:

  1. Melhorar a estabilidade do bot.
  2. Lidar com captchas de forma mais eficaz.
  3. Evitar a detecção de bot pelos provedores de e-mail.

Por favor, compartilhe! 📚 Estou aberto a sugestões, dicas de bibliotecas, ou até mesmo estratégias que possam ajudar a contornar esses desafios.

📝 Exemplos de Código

Segue um pequeno trecho do meu código atual para dar mais contexto:

import logging
import random
import time
from task import generate_random_names, generate_random_surnames, get_phone_number, get_verification_code, fetch_emails, connect_db, save_email
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError

GOOGLE_SIGNUP_URL = "https://accounts.google.com/signup/v2/createaccount?flowName=GlifWebSignIn&flowEntry=SignUp"
PROXY_SERVER = "Itc6tLLIatUoR93k:wifi;us;;;newland@rotating.proxyempire.io:9000"
DEFAULT_WAIT_TIME = 5000
PHONE_NUMBER_AND_ID = get_phone_number()

def random_delay(min_sec=2, max_sec=5):
    delay = random.uniform(min_sec, max_sec)
    time.sleep(delay)
    return delay

def random_sex():
    set_random_sex = ["Male", "Female", "Rather not say"]
    return random.choice(set_random_sex)

class EmailAutomation:
    def __init__(self, proxy, proxy_username, proxy_password):
        self.playwright = sync_playwright().start()
        self.browser = self.playwright.chromium.launch(
            headless=False,
            proxy={
                "server": proxy,
                "username": proxy_username,
                "password": proxy_password
            } if proxy else None
        )

        self.context = self.browser.new_context(
            user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
            viewport={"width": random.randint(1024, 1820), "height": random.randint(768, 1080)},
            locale="en-US",
            timezone_id="America/New_York"
        )
        self.page = self.context.new_page()
        logging.info("Browser opened")

    def simulate_typing(self, locator, text, delay_min=0.1, delay_max=0.3):
        """Função para simular a digitação humana de forma mais realista."""
        locator.clear()
        for char in text:
            locator.type(char)
            time.sleep(random.uniform(delay_min, delay_max))

    def create_email_account(self, email, gmail, password):
        try:
            # abrir página de signup do Google
            self.page.goto(GOOGLE_SIGNUP_URL)

            first_name = generate_random_names()
            last_name = generate_random_surnames()
            next_button = self.page.get_by_role('button')
            next_button_text = self.page.get_by_text("Next")

            try:
                if not self.page.locator('input#day').is_visible():
                    self.page.locator('input#firstName').clear()
                    self.page.fill('input#firstName', first_name)
                    self.page.locator('input#lastName').clear()
                    self.page.fill('input#lastName', last_name)
                    logging.info(f"Filled: {first_name} {last_name}")
                    next_button.click()

                self.page.wait_for_selector('input#day', timeout=DEFAULT_WAIT_TIME)
                self.page.locator('input#day').clear()
                self.page.fill('input#day', str(random.randint(1, 30)))
                self.page.get_by_label('Month').select_option("January")
                self.page.locator('input#year').clear()
                self.page.fill("input#year", str(random.randint(1940, 2000)))
                gender_select = self.page.locator("select[id = 'gender']")
                gender_select.select_option(label=f"{random_sex()}")
                next_button.click()

                time.sleep(2)
                if self.page.locator("id=selectionc4").is_visible():
                    select_radio_email = self.page.locator("id=selectionc4")
                    select_radio_email.click()

                self.page.wait_for_selector("input[name='Username']", timeout=DEFAULT_WAIT_TIME)
                self.page.locator("input[name='Username']").fill(gmail)
                logging.info("Input gmail filled")
                next_button_text.click()

                self.page.wait_for_selector("input[name='Passwd']", timeout=DEFAULT_WAIT_TIME)
                self.page.locator("input[name='Passwd']").fill(password)
                self.page.locator("input[name='PasswdAgain']").fill(password)
                logging.info("Password filled")
                next_button.click()

                self.page.wait_for_selector("input#phoneNumberId", timeout=DEFAULT_WAIT_TIME)
                self.page.locator("input#phoneNumberId").clear()
                self.page.fill("input#phoneNumberId", str(PHONE_NUMBER_AND_ID[0]))
                logging.info(f"Phone number filled: {str(PHONE_NUMBER_AND_ID[0])}")
                next_button.click()

                self.page.wait_for_selector("input#code", timeout=DEFAULT_WAIT_TIME)

                verification_code = get_verification_code()

                if verification_code:
                    self.page.locator("input#code").clear()
                    self.page.fill("input#code", verification_code)
                    next_button.click()
                    logging.info(f"Verification code filled successfully: {verification_code}")
                else:
                    logging.error(f"Error to fill verification code: {verification_code}")
            except PlaywrightTimeoutError as e:
                logging.error(f"Timeout encountered: {e}")
                return False
        except Exception as e:
            logging.error(f"Error creating email account: {email}")
            return False

    def close(self):
        if self.browser:
            self.browser.close()
            logging.info("Browser closed successfully")

def main():
    db = connect_db()
    if not db:
        logging.error("Failed to connect to database")
        return
    
    emails = fetch_emails(db)

    if not emails:              
        logging.error("No emails found for processing")
        db.close()
        return
    
    automation = None
    try:
        automation = EmailAutomation(proxy=None, proxy_username="gabrielmanna1994@gmail.com", proxy_password="QGN@bh2YJYLQxM8")
        for entry in emails:
            email = entry['email']
            password = entry['senha']
            gmail = entry['primeiro_nome']
            if not automation.create_email_account(email, gmail, password):
                logging.warning(f"Failed to create email {email}. Moving to next.")
    finally:
        if automation:
            automation.close()
        db.close()

if __name__ == "__main__":
    main()

Agradeço desde já pela atenção de todos! Vamos resolver isso juntos. 💪


📩 Estou à disposição para responder dúvidas e discutir ideias nos comentários. 😊

Porque você precisa criar tantos e-mails? Caso seja necessário criar diversos e-mails e que não precise de um servidor externo, acho mais fácil criar seu próprio servidor de e-mail. Se for externo eles tem diversas formas de identificar abusos, então vai ser bem difícil ficar adaptando código.

Preciso para um projeto de geração de leads. Se eu contratar um servidor consiguirei obter o objetivo de criar diversos emails's?
Você pode criar um servidor de e-mail open, só vai ser necessário um domínio e onde hospedar, tem alguns aqui: https://github.com/Mindbaz/awesome-opensource-email

Esses provedores tem investimentos BEM significativos para barrar qualquer iteração de bots (isso já deu muito problema), tem uma volumetria de quantos e-mails precisa criar a cada vez que seu bot roda ?

Não tem uma quantia específica, irei rodar este bot diariamente, mas o cenário ideial é de 100 a 200 contas diárias.

Cara, eu tentei recriar essa automação utilizando um outro framework que eu to acostumado a trabalhar, eu ainda não coloquei extresse nele mais o pouco que eu testei me pareceu bem resiliente, se quiser posso tentar te ajudar com isso ... eu vou te mandar o link do repositorio qualquer coisa me chama no linkedin eu vejo como posso te ajudar mais ...

obs.: No momento de publicação desse comentario eu me esqueci de colocar como rodar o bot no README, então qualquer coisa me chama no linkedin que eu tento te ajudar, mas basicamente é preciso criar um ambiente venv e instalar os pacotes da requirements.txt

comando para o console:

pip install --upgrade -r requirements.txt

LINKEDIN: https://www.linkedin.com/in/renan-maciel/ REPOSITORIO: https://github.com/renansilvamaciel/createAccountGoogleMail