Monitoring for handshake TLS in chrome/selenium headless mode.
I have a script that access a URL that ask for certificate, when i'm using kaspersky anti virus it prompt me for a certificate selection, but when i turn off kaspersky, then no prompt appear.
I'm trying to do what kaspersky is doing, i want to choose the certificate and use chrome on headless mode.
This is my scriptdef acessar_portal_nfce_auto(pasta_download, log_callback, progress_callback, status_callback, status_chave_callback): global processed_count, chrome_initial_chrome_pids, chrome_initial_chromedriver_pids initial_chrome_pids, initial_chromedriver_pids = get_chrome_processes() chrome_initial_chrome_pids = set(initial_chrome_pids) chrome_initial_chromedriver_pids = set(initial_chromedriver_pids) chrome_options = Options() prefs = { "download.prompt_for_download": False, "download.directory_upgrade": True, "safebrowsing.enabled": True, "download.default_directory": pasta_download, "plugins.always_open_pdf_externally": True } chrome_options.add_experimental_option("prefs", prefs) chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") if modo_oculto.get(): chrome_options.add_argument("--headless") log_callback("🔍 Modo oculto ativado - Chrome será executado em segundo plano") else: log_callback("🖥️ Modo visível - Chrome será exibido durante a execução") service = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service, options=chrome_options) # Ativa o botão Cancelar APENAS após o driver ser criado root.after(0, lambda: btn_cancelar.config(state="normal")) try: log_callback("\n🔗 Acessando portal NFCE...") status_callback("Acessando portal...") driver.get("https://dfe-portal.svrs.rs.gov.br/NfceSSL/DownloadXmlDfe") processed_count = 0 total_chaves = chave_queue.qsize() while not chave_queue.empty(): if cancel_event.is_set(): status_callback("Cancelando Processo") log_callback("❌ Processo cancelado pelo usuário") log_em_arquivo(pasta_download, "Cancelado pelo usuário") break try: chave_acesso = chave_queue.get(timeout=1) except queue.Empty: time.sleep(1) continue # VERIFICA SE ESTA CHAVE JÁ FOI CONCLUÍDA (DOUBLE-CHECK) if chave_acesso in chaves_processadas: processed_count += 1 progress_callback(processed_count, chave_queue.qsize()) log_callback(f"⏭️ Chave já concluída anteriormente, pulando: {chave_acesso}") continue processed_count += 1 sucesso = False tentativa = 1 while not sucesso and tentativa <= max_tentativas: if cancel_event.is_set(): break try: tempo_apos_consulta = int(entry_apos_consulta.get()) except: tempo_apos_consulta = 5 try: tempo_download = int(entry_download.get()) except: tempo_download = 8 try: tempo_espera = int(entry_espera.get()) except: tempo_espera = 30 try: timeout_download = int(entry_timeout_download.get()) except: timeout_download = 12 if cancel_event.is_set(): break try: status_callback(f"Chave {processed_count}: Tentativa {tentativa} - Aguardando comando...") while pause_event.is_set(): status_callback("⏸️ Pausado") time.sleep(1) if cancel_event.is_set(): break status_chave_callback(chave_acesso, "Consultando...", "#ffff66") status_callback(f"Chave {processed_count}: Tentativa {tentativa} - Consultando...") log_callback(f"\n➡️ ({processed_count}) Tentativa {tentativa} - Consultando chave: {chave_acesso}") progress_callback(processed_count, chave_queue.qsize()) if cancel_event.is_set(): break wait = WebDriverWait(driver, tempo_apos_consulta + 15) campo_chave = wait.until(EC.presence_of_element_located((By.ID, "ChaveAcessoDfe"))) botao_consultar = wait.until( EC.element_to_be_clickable( (By.XPATH, "//button[@type='submit' and contains(@class, 'btn-primary')]") ) ) campo_chave.clear() campo_chave.send_keys(chave_acesso) botao_consultar.click() status_callback("Consultando...") time.sleep(tempo_apos_consulta) if cancel_event.is_set(): break botao_download = WebDriverWait(driver, timeout_download).until( EC.element_to_be_clickable((By.ID, "btnExportar")) ) botao_download.click() status_callback("Download iniciado") log_callback("⏳ Download do XML iniciado...") log_em_arquivo(pasta_download, f"Download iniciado para chave {chave_acesso}") status_chave_callback(chave_acesso, "Baixando...", "#ffa500") for _ in range(tempo_download): time.sleep(1) while pause_event.is_set(): status_callback("⏸️ Pausado durante download") time.sleep(1) if cancel_event.is_set(): break log_callback(f"✅ Download da chave {chave_acesso} concluído!") status_callback("Download concluído") log_em_arquivo(pasta_download, f"Download concluído para chave {chave_acesso}") log_callback("🔄 Renomeando arquivo baixado...") renomear_arquivos_xml(pasta_download, log_callback) sucesso = True chaves_processadas.add(chave_acesso) # MARCA COMO PROCESSADA status_chave_callback(chave_acesso, "Concluído", "#32cd32") except Exception as e: if cancel_event.is_set() and ( "Failed to establish a new connection" in str(e) or "chrome not reachable" in str(e).lower() or "Max retries exceeded" in str(e) or "disconnected" in str(e).lower() ): log_callback("⚠️ Cancelamento detectado durante operação Selenium.") break log_callback(f"⚠️ Falha na tentativa {tentativa} para a chave {chave_acesso}: {e}") status_callback("Repetindo tentativa") log_em_arquivo(pasta_download, f"Falha tentativa {tentativa} para chave {chave_acesso}: {e}") tentativa += 1 if tentativa > max_tentativas: log_callback("❌ Tentativas excedidas! Pulando para próxima chave.") status_callback("Falha - pulando chave") log_em_arquivo(pasta_download, f"Chave {chave_acesso} pulada após {max_tentativas} tentativas") status_chave_callback(chave_acesso, "Falhou", "#ff4d4d") break for t in range(tempo_espera, 0, -1): if cancel_event.is_set(): break while pause_event.is_set(): status_callback("⏸️ Pausado durante espera") time.sleep(1) progress_callback(processed_count, chave_queue.qsize()) time.sleep(1) if cancel_event.is_set(): break try: driver.get("https://dfe-portal.svrs.rs.gov.br/NfceSSL/DownloadXmlDfe") except Exception: break progress_callback(processed_count, chave_queue.qsize()) if not cancel_event.is_set(): status_callback("Todos os downloads concluídos!") log_callback("\n🎉 Todas as consultas foram processadas com sucesso!") log_em_arquivo(pasta_download, "Todas as consultas concluídas com sucesso") except Exception as e: if cancel_event.is_set() and ( "Failed to establish a new connection" in str(e) or "chrome not reachable" in str(e).lower() or "Max retries exceeded" in str(e) or "disconnected" in str(e).lower() ): log_callback("⚠️ Chrome foi encerrado antes do término (cancelamento detectado).") else: log_callback(f"💥 Erro fatal: {e}") status_callback("Erro fatal") log_em_arquivo(pasta_download, f"Erro fatal: {e}") finally: try: driver.quit() except Exception: pass if cancel_event.is_set(): killed = kill_chrome_processes(initial_chrome_pids, initial_chromedriver_pids) if killed > 0: log_callback(f"🔴 {killed} processos do Chrome encerrados forçadamente")
Please sign in to leave a comment.