import httpx import re import time import random from typing import List, Optional from urllib.parse import urlparse from rich.console import Console import logging # Configuração de logging logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") logger = logging.getLogger(__name__) # Inicializa o console do rich para mensagens coloridas console = Console() class ClickSimulator: def __init__( self, request_interval: float = 2.0, max_requests: int = 50, timeout: float = 15.0 ): """ Inicializa o simulador de cliques para Google, Facebook ou Instagram. Args: request_interval: Intervalo entre requisições em segundos. max_requests: Número máximo de requisições a enviar. timeout: Tempo máximo de espera por requisição em segundos. """ self.request_interval = request_interval self.max_requests = max_requests self.timeout = timeout self.total_clicks = 0 self.client = httpx.Client( timeout=self.timeout, headers=self._get_random_headers(), follow_redirects=True ) def _get_random_headers(self) -> dict: """Retorna headers aleatórios para simular navegadores diferentes.""" user_agents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0", "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1", ] return { "User-Agent": random.choice(user_agents), "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "same-origin", } def validate_url(self, url: str, platform: str) -> bool: """Valida se a URL é válida e pertence à plataforma escolhida.""" try: parsed = urlparse(url) if platform.lower() == "google": return bool(parsed.scheme in ["http", "https"] and "google" in parsed.netloc.lower()) elif platform.lower() == "facebook": return bool(parsed.scheme in ["http", "https"] and any(domain in parsed.netloc.lower() for domain in ["facebook", "fb"])) elif platform.lower() == "instagram": return bool(parsed.scheme in ["http", "https"] and "instagram" in parsed.netloc.lower()) return False except: return False def simulate_clicks(self, url: str, platform: str) -> None: """ Simula cliques enviando requisições GET para o link fornecido. Args: url: URL do Google, Facebook ou Instagram. platform: Plataforma escolhida ("google", "facebook", "instagram"). """ if not self.validate_url(url, platform): console.print(f"[red]Erro: URL inválida ou não pertence ao {platform}.[/red]") return url = url.strip() for i in range(self.max_requests): try: # Atualiza headers para cada requisição self.client.headers = self._get_random_headers() if platform.lower() == "google": self.client.headers["Referer"] = "https://www.google.com/" elif platform.lower() == "facebook": self.client.headers["Referer"] = "https://www.facebook.com/" elif platform.lower() == "instagram": self.client.headers["Referer"] = "https://www.instagram.com/" response = self.client.get(url) # Verifica o status da resposta if response.status_code == 200: # Tenta extrair o título da página title_match = re.search(r'(.*?)', response.text, re.IGNORECASE) title = title_match.group(1) if title_match else "Sem título" self.total_clicks += 1 console.print( f"[green]Clique {self.total_clicks}/{self.max_requests} OK | " f"Título: {title} | Plataforma: {platform}[/green]" ) else: console.print( f"[red]Erro: Status {response.status_code} ao acessar {url}[/red]" ) except httpx.HTTPError as e: console.print(f"[red]Erro na requisição: {e}[/red]") except Exception as e: console.print(f"[red]Erro inesperado: {e}[/red]") # Aguarda um intervalo aleatório para simular comportamento humano time.sleep(self.request_interval + random.uniform(0, 0.5)) console.print(f"[yellow]Finalizado: {self.total_clicks} cliques enviados para {platform}.[/yellow]") def __del__(self): """Fecha o cliente HTTP ao destruir o objeto.""" self.client.close() def show_menu() -> tuple: """Exibe o menu e coleta a escolha do usuário.""" while True: console.print(""" [bold cyan]=== Painel de Simulação de Cliques ===[/bold cyan] [1] Google [2] Facebook [3] Instagram """) try: choice = input("Escolha uma opção (1, 2 ou 3): ").strip() if choice in ["1", "2", "3"]: platform = "Google" if choice == "1" else "Facebook" if choice == "2" else "Instagram" url = input(f"Digite o link do {platform}: ").strip() return platform, url console.print("[red]Opção inválida! Escolha 1, 2 ou 3.[/red]") except KeyboardInterrupt: console.print("[yellow]Programa encerrado pelo usuário.[/yellow]") exit() except: console.print("[red]Erro ao processar entrada. Tente novamente.[/red]") # Exemplo de uso if __name__ == "__main__": # Configurações simulator = ClickSimulator( request_interval=2.0, # 2 segundos entre requisições max_requests=50, # Máximo de 50 requisições timeout=15.0 # Timeout de 15 segundos ) # Mostra o menu e coleta a escolha platform, url = show_menu() # Executa a simulação console.print(f"[cyan]Iniciando simulação para {platform} com o link: {url}[/cyan]") simulator.simulate_clicks(url, platform)