Automação Web com Selenium em Python: Conceitos Essenciais e Aplicações

Introdução ao Selenium

Selenium é um robusto framework para automação de aplicações web. Ele permite o desenvolvimento de scripts que simulam a interação humana com navegadores, como cliques em botões, preenchimento de formulários e navegação entre páginas. Além disso, possibilita a extração de dados de interfaces web, como informações de bilhetes, vagas de emprego ou cotações de ações, para posterior análise.

O funcionamento do Selenium baseia-se em uma arquitetura de comunicação entre sua biblioteca cliente (utilizada pelo seu código de automação), um driver de navegador e o próprio navegador. Quando seu programa executa uma ação, a biblioteca cliente envia uma requisição HTTP ao driver do navegador. Este, por sua vez, traduz e encaminha a requisição ao navegador, que executa a operação. O resultado da operação é então retornado ao driver e, subsequentemente, à sua aplicação via resposta HTTP, permitindo que seu código interprete o sucesso ou falha da ação.

O projeto Selenium oferece bibliotecas cliente para diversas linguagens de programação, incluindo Python, Java, JavaScript e Ruby, facilitando a integração em diferentes ambientes de desenvolvimento. O driver do navegador é um executável separado, fornecido pelos fabricantes dos navegadores (como Chrome, Firefox, etc.), e sua versão deve ser compatível com a versão do navegador instalado em sua máquina.

Configuração do Ambiente

Para iniciar com Selenium, são necessários dois componentes principais: a biblioteca cliente e o driver do navegador.

Instalação da Biblioteca Cliente Selenium para Python

A instalação da biblioteca cliente em Python é direta, utilizando o gerenciador de pacotes pip:

pip install selenium

Instalação do Driver do Navegador

Recomenda-se o uso do Google Chrome devido ao seu suporte maduro ao Selenium. Certifique-se de que o Chrome esteja instalado. Em seguida, baixe o ChromeDriver a partir da página oficial do projeto.

Atenção: A versão do ChromeDriver deve ser compatível com as primeiras duas casas decimais da versão do seu Google Chrome. Por exemplo, se seu Chrome for v119.0.X.X, você precisará de um ChromeDriver v119.X.X.X.

Após baixar o arquivo executável do driver (ex: chromedriver.exe ou chromedriver), é crucial adicioná-lo ao PATH do seu sistema operacional para que o Selenium possa encontrá-lo automaticamente, ou especificar o caminho completo no código. A adição ao PATH é geralmente preferível para maior flexibilidade.

Exemplo Básico de Automação

Com a biblioteca e o driver instalados, podemos executar um script simples para abrir uma página web:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

# Configura o driver do Chrome usando o webdriver_manager (recomendado para gerenciar o driver automaticamente)
# Isso baixa e gerencia o driver para você, simplificando a instalação.
servico_chrome = ChromeService(ChromeDriverManager().install())
navegador_web = webdriver.Chrome(service=servico_chrome)

try:
    # Abre uma URL específica
    navegador_web.get('https://www.google.com')
    print(f"Título da página: {navegador_web.title}")
    time.sleep(2) # Espera 2 segundos para visualização

finally:
    # Fecha o navegador e encerra o processo do driver
    navegador_web.quit()

Fundamentos do Selenium com Python

Estratégias de Localização de Elementos Web

Para interagir com uma página web, o Selenium precisa "encontrar" os elementos com os quais você deseja trabalhar. Existem diversas estratégias para localizar elementos, cada uma útil em diferentes cenários:

  1. ID: Busca elementos pelo atributo id. É a forma mais robusta e preferível quando o ID é único na página.
  2. NAME: Busca elementos pelo atributo name.
  3. CLASS_NAME: Busca elementos pela classe CSS.
  4. TAG_NAME: Busca elemantos pelo nome da tag HTML (ex: <input>, <a>).
  5. LINK_TEXT: Busca links (tag <a>) pelo texto visível completo.
  6. PARTIAL_LINK_TEXT: Busca links pelo texto visível parcial.
  7. XPATH: Uma linguagem poderosa para localizar elementos em documentos XML/HTML. Permite localizar elementos com base em sua estrutura e atributos.
  8. CSS_SELECTOR: Utiliza seletores CSS para encontrar elementos. É rápido e geralmente mais legível que XPath.

A tabela a seguir detalha os métodos correspondentes no Selenium para localizar um ou múltiplos elementos:

Localizar Único Elemento Localizar Múltiplos Elementos Descrição
find_element(By.ID, "id_valor") find_elements(By.ID, "id_valor") Pelo atributo id do elemento.
find_element(By.NAME, "name_valor") find_elements(By.NAME, "name_valor") Pelo atributo name do elemento.
find_element(By.XPATH, "xpath_expressao") find_elements(By.XPATH, "xpath_expressao") Pela expressão XPath.
find_element(By.LINK_TEXT, "texto_completo") find_elements(By.LINK_TEXT, "texto_completo") Pelo texto exato do link.
find_element(By.PARTIAL_LINK_TEXT, "texto_parcial") find_elements(By.PARTIAL_LINK_TEXT, "texto_parcial") Pelo texto parcial do link.
find_element(By.TAG_NAME, "tag_nome") find_elements(By.TAG_NAME, "tag_nome") Pelo nome da tag HTML.
find_element(By.CLASS_NAME, "classe_css") find_elements(By.CLASS_NAME, "classe_css") Pelo nome da classe CSS.
find_element(By.CSS_SELECTOR, "seletor_css") find_elements(By.CSS_SELECTOR, "seletor_css") Pelo seletor CSS.

Exemplos de Localização de Elementos

Consideremos o seguinte snippet HTML de uma página de busca:

<html>
  <head></head>
  <body link="#0000cc">
    <a id="logo_resultado" href="/" onmousedown="return c({'fm':'tab','tab':'logo'})"></a>
    <form id="formulario_busca" class="fm" name="f" action="/s">
      <span class="botao_busca_img"></span>
        <input id="campo_texto" class="campo_entrada" name="termo_pesquisa" value="" maxlength="255" autocomplete="off">
    </form>
    <a class="menu_nav" href="http://noticias.exemplo.com" name="noticias_link">Notícias</a>
    <a class="menu_nav" href="http://www.exemplo.com/home" name="home_link">Minha Página</a>
  </body>
</html>

Para localizar o campo de texto (<input>) usando diferentes métodos:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

# Configuração do driver
servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.get("data:text/html,<html><body link='#0000cc'><a id='logo_resultado' href='/'></a><form id='formulario_busca' class='fm' name='f' action='/s'><span class='botao_busca_img'></span><input id='campo_texto' class='campo_entrada' name='termo_pesquisa' value='' maxlength='255' autocomplete='off'></form><a class='menu_nav' href='http://noticias.exemplo.com' name='noticias_link'>Notícias</a><a class='menu_nav' href='http://www.exemplo.com/home' name='home_link'>Minha Página</a></body></html>")

try:
    # Por ID
    campo_por_id = navegador.find_element(By.ID, "campo_texto")
    print(f"Encontrado por ID: {campo_por_id.tag_name} com ID='{campo_por_id.get_attribute('id')}'")

    # Por NAME
    campo_por_name = navegador.find_element(By.NAME, "termo_pesquisa")
    print(f"Encontrado por NAME: {campo_por_name.tag_name} com NAME='{campo_por_name.get_attribute('name')}'")

    # Por CLASS_NAME
    campo_por_classe = navegador.find_element(By.CLASS_NAME, "campo_entrada")
    print(f"Encontrado por CLASS_NAME: {campo_por_classe.tag_name} com CLASS='{campo_por_classe.get_attribute('class')}'")

    # Por TAG_NAME
    campo_por_tag = navegador.find_element(By.TAG_NAME, "input")
    print(f"Encontrado por TAG_NAME: {campo_por_tag.tag_name}")

    # Por XPATH (algumas opções)
    campo_xpath_1 = navegador.find_element(By.XPATH, "//input[@id='campo_texto']")
    campo_xpath_2 = navegador.find_element(By.XPATH, "//input[@name='termo_pesquisa']")
    campo_xpath_3 = navegador.find_element(By.XPATH, "//form[@id='formulario_busca']/span/input")
    print(f"Encontrado por XPATH: {campo_xpath_1.tag_name}")

    # Por CSS_SELECTOR (algumas opções)
    campo_css_1 = navegador.find_element(By.CSS_SELECTOR, "#campo_texto")
    campo_css_2 = navegador.find_element(By.CSS_SELECTOR, "[name='termo_pesquisa']")
    campo_css_3 = navegador.find_element(By.CSS_SELECTOR, "input.campo_entrada")
    print(f"Encontrado por CSS_SELECTOR: {campo_css_1.tag_name}")

    # Localizando links
    link_noticias = navegador.find_element(By.LINK_TEXT, "Notícias")
    print(f"Link 'Notícias' encontrado: {link_noticias.get_attribute('href')}")

    link_parcial = navegador.find_element(By.PARTIAL_LINK_TEXT, "Minha")
    print(f"Link parcial 'Minha' encontrado: {link_parcial.get_attribute('href')}")

finally:
    navegador.quit()

Métodos Comuns de Interação com o Navegador e Elementos

O objeto WebDriver e os objetos de elemento web oferecem uma série de métodos para controlar o navegador e interagir com a interface:

Método/Propriedade Descrição
set_window_size(width, height) Define as dimensões da janela do navegador.
back() Navega para a página anterior no histórico.
forward() Navega para a próxima página no histórico.
refresh() Recarrega a página atual.
clear() (em elemento) Limpa o conteúdo de um campo de texto.
send_keys(value) (em elemento) Simula a digitação de texto ou teclas especiais em um campo.
click() (em elemento) Simula um clique em um elemento.
submit() (em elemento) Envia um formulário ao qual o elemento pertence.
get_attribute(name) (em elemento) Retorna o valor de um atributo HTML (ex: 'href', 'value').
is_displayed() (em elemento) Verifica se um elemento está visível na página.
size (em elemento) Retorna as dimensões (largura e altura) do elemento.
text (em elemento) Retorna o texto visível dentro de um elemento.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)

try:
    navegador.get("https://www.google.com")
    time.sleep(1)

    print("Atualizando a página...")
    navegador.refresh()
    time.sleep(1)

    print("Definindo o tamanho da janela...")
    navegador.set_window_size(1024, 768)
    time.sleep(1)

    # Localiza o campo de pesquisa por ID e digita algo
    campo_pesquisa = navegador.find_element(By.NAME, "q")
    campo_pesquisa.send_keys("Selenium Web Automation")
    time.sleep(1)

    # Simula o envio do formulário (clica no botão de pesquisa)
    botao_pesquisar = navegador.find_element(By.NAME, "btnK")
    botao_pesquisar.click()
    time.sleep(2)

    # Voltar para a página anterior
    navegador.back()
    time.sleep(1)

    # Ir para a próxima página (a página de resultados da busca)
    navegador.forward()
    time.sleep(2)

finally:
    navegador.quit()

Eventos de Mouse com ActionChains

Para interações mais complexas com o mouse, como arrastar e soltar, cliques duplos ou passar o mouse sobre um elemento (hover), o Selenium oferece a classe ActionChains.

Método Descrição
ActionChains(driver) Construtor, inicia uma cadeia de ações.
context_click(element) Simula um clique com o botão direito do mouse em um elemento.
double_click(element) Simula um clique duplo em um elemento.
drag_and_drop(source, target) Arrasta um elemento (source) e solta-o sobre outro (target).
move_to_element(element) Move o cursor do mouse para o centro de um elemento.
perform() Executa todas as ações armazenadas na cadeia. Essencial para que as ações aconteçam.
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.get("https://www.google.com")
navegador.maximize_window() # Maximiza a janela para garantir que elementos estejam visíveis
time.sleep(2)

try:
    # Tentar interagir com o link de "Configurações" se estiver visível
    # O Google muda a UI frequentemente, então o seletor pode precisar ser ajustado
    try:
        elemento_configuracoes = navegador.find_element(By.XPATH, "//div[@aria-label='Configurações']")
        print("Elemento 'Configurações' encontrado.")
        
        # Realiza a ação de passar o mouse sobre o elemento
        ActionChains(navegador).move_to_element(elemento_configuracoes).perform()
        time.sleep(2)
        print("Mouse passado sobre 'Configurações'.")

        # Procura por um link ou opção que aparece após o hover
        # Exemplo hipotético: clicar em "Configurações de pesquisa"
        link_configuracao_pesquisa = navegador.find_element(By.LINK_TEXT, "Configurações de pesquisa")
        link_configuracao_pesquisa.click()
        time.sleep(3)
        print("Clicou em 'Configurações de pesquisa'.")

    except Exception as e:
        print(f"Não foi possível interagir com o menu de configurações (pode ter mudado a UI ou elemento não encontrado): {e}")

finally:
    navegador.quit()

Eventos de Teclado

Além da digitação de texto com send_keys(), o Selenium permite simular o pressionamento de teclas especiais ou combinações de teclas através do módulo Keys de selenium.webdriver.common.keys.

Simulação de Tecla Descrição
send_keys(Keys.BACK_SPACE) Tecla BackSpace.
send_keys(Keys.SPACE) Barra de espaço.
send_keys(Keys.TAB) Tecla Tab.
send_keys(Keys.ESCAPE) Tecla Esc.
send_keys(Keys.ENTER) Tecla Enter.
send_keys(Keys.CONTROL, 'a') Combinação Ctrl+A (selecionar tudo).
send_keys(Keys.CONTROL, 'c') Combinação Ctrl+C (copiar).
send_keys(Keys.CONTROL, 'x') Combinação Ctrl+X (recortar).
send_keys(Keys.CONTROL, 'v') Combinação Ctrl+V (colar).
send_keys(Keys.F1) Teclas de função F1 a F12.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.get("https://www.google.com")
time.sleep(2)

try:
    campo_entrada = navegador.find_element(By.NAME, "q")
    campo_entrada.send_keys("Automação de Testes")
    time.sleep(1)

    # Simula o pressionar da tecla ENTER para submeter a busca
    campo_entrada.send_keys(Keys.ENTER)
    time.sleep(3)

    # Voltar ao campo de pesquisa (se ainda estiver na página de resultados e o campo existir)
    navegador.back()
    time.sleep(2)
    
    campo_entrada = navegador.find_element(By.NAME, "q")
    campo_entrada.click() # Clica no campo para focar
    time.sleep(1)
    
    # Selecionar todo o texto no campo e depois apagar
    ActionChains(navegador).key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).perform()
    time.sleep(1)
    campo_entrada.send_keys(Keys.BACK_SPACE)
    time.sleep(1)
    
    campo_entrada.send_keys("Selenium com Python")
    time.sleep(1)
    campo_entrada.send_keys(Keys.RETURN) # Outra forma de simular ENTER
    time.sleep(3)

finally:
    navegador.quit()

Obtenção de Informações para Asserções

Para verificar o estado da página ou de elementos, o Selenium permite extrair informações cruciais para a validação de testes (asserções).

Propriedade Descrição
title Obtém o título da página atual.
current_url Obtém a URL da página atual.
text (em elemento) Obtém o texto visível de um elemento.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.get("https://www.google.com")
time.sleep(2)

print('=== Antes da Busca ===')
titulo_inicial = navegador.title
url_inicial = navegador.current_url
print(f"Título da Página: {titulo_inicial}")
print(f"URL Atual: {url_inicial}")

campo_pesquisa = navegador.find_element(By.NAME, "q")
campo_pesquisa.send_keys("Selenium")
campo_pesquisa.send_keys(Keys.ENTER)
time.sleep(3)

print('\n=== Após a Busca ===')
titulo_apos_busca = navegador.title
url_apos_busca = navegador.current_url
print(f"Novo Título da Página: {titulo_apos_busca}")
print(f"Nova URL Atual: {url_apos_busca}")

# Tentar obter um elemento que mostre o número de resultados (pode variar entre sites)
try:
    # Exemplo para Google: o elemento que mostra a quantidade de resultados pode ser complexo
    # Uma forma mais robusta seria procurar pelo texto "resultados" ou similar.
    # Para simplificar, vou procurar por um elemento que contenha texto de resumo.
    info_resultados = navegador.find_element(By.ID, "result-stats").text
    print(f"Informação de Resultados: {info_resultados}")
except Exception as e:
    print(f"Não foi possível encontrar a informação de resultados: {e}")

navegador.quit()

Estratégias de Espera

As aplicações web modernas são dinâmicas, com elementos que carregam assincronamente. Para evitar erros de "elemento não encontrado", é essencial usar esperas:

  • Espera Implícita: Define um tempo máximo que o WebDriver deve esperar ao tentar encontrar um elemento antes de lançar uma exceção. Aplica-se a todas as buscas de elementos.
  • Espera Explícita: Permite definir condições específicas para esperar que um elemento apareça ou mude de estado, com um tempo limite máximo. Usa WebDriverWait e expected_conditions.
  • time.sleep(): Uma espera estática e não recomendada em automação real, pois sempre espera o tempo especificado, mesmo que o elemento apareça antes, tornando os testes lentos.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10) # Espera implícita de 10 segundos

try:
    navegador.get("https://www.google.com")
    
    campo_busca = navegador.find_element(By.NAME, "q")
    campo_busca.send_keys("Esperas no Selenium")
    campo_busca.send_keys(Keys.ENTER)
    
    print("Página de resultados carregada.")
    # Com a espera implícita, não precisamos de time.sleep() aqui,
    # a menos que haja uma necessidade específica de atraso para observação.
    time.sleep(3) 

finally:
    navegador.quit()

Localizando Múltiplos Elementos

Quando você precisa interagir com uma coleção de elementos (por exemplo, todos os resultados de uma busca ou itens de uma lista), utilize os métodos find_elements(). Eles retornam uma lista de elementos que correspondem ao critério.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(5)
navegador.get("https://www.google.com")

try:
    campo_pesquisa = navegador.find_element(By.NAME, "q")
    campo_pesquisa.send_keys("Python Selenium")
    campo_pesquisa.send_keys(Keys.ENTER)
    time.sleep(3) # Pequena pausa para a página carregar

    # Localiza todos os títulos dos resultados da busca
    # O XPath para resultados do Google pode variar. Este é um exemplo comum.
    titulos_resultados = navegador.find_elements(By.XPATH, "//div[@id='rso']/div/div/div[1]/div/a/h3")
    print(f"Foram encontrados {len(titulos_resultados)} resultados de títulos.")

    for i, titulo_elemento in enumerate(titulos_resultados):
        texto_titulo = titulo_elemento.text
        print(f"Título {i+1}: {texto_titulo}")
        
        # Clicar em um dos links, voltar e continuar o loop (exemplo)
        if i == 0: # Clica apenas no primeiro resultado para demonstração
            titulo_elemento.click()
            print(f"Clicado no título: '{texto_titulo}'")
            time.sleep(3)
            navegador.back()
            time.sleep(2)
            # Re-localizar os elementos após o 'back()' pois o DOM pode ter sido recarregado
            titulos_resultados = navegador.find_elements(By.XPATH, "//div[@id='rso']/div/div/div[1]/div/a/h3")

finally:
    navegador.quit()

Alternando Entre Frames (iframes)

Páginas web frequentemente utilizam <iframe>s para incorporar conteúdo de outras fontes ou organizar seções. O Selenium só pode interagir com elementos dentro do frame ativo. Para acessar elementos em um <iframe>, é necessário alternar para ele usando switch_to.frame().

Método Descrição
switch_to.frame(frame_reference) Muda o foco do WebDriver para o frame especificado. frame_reference pode ser o ID, nome ou o próprio elemento iframe.
switch_to.default_content() Retorna o foco do WebDriver para o conteúdo principle da página (fora de qualquer frame).
switch_to.parent_frame() Retorna o foco para o frame pai do frame atual.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)
navegador.get("http://mail.126.com") # Exemplo de site com iframe de login

try:
    print("Aguardando o carregamento da página de login...")
    time.sleep(3) # Aguarda para garantir que o iframe seja carregado no DOM

    # O iframe de login do 126.com geralmente tem um ID ou nome
    # No entanto, a forma como os iframes são carregados pode variar.
    # Vamos tentar localizar o iframe primeiro.
    try:
        iframe_login = navegador.find_element(By.XPATH, "//iframe[starts-with(@id, 'login_frame') or starts-with(@name, 'login_frame')]")
        navegador.switch_to.frame(iframe_login)
        print("Foco alternado para o iframe de login.")

        # Agora, podemos interagir com elementos dentro do iframe
        campo_usuario = navegador.find_element(By.NAME, "email")
        campo_usuario.clear()
        campo_usuario.send_keys("seu_usuario_teste")
        print("Usuário preenchido.")
        
        campo_senha = navegador.find_element(By.NAME, "password")
        campo_senha.clear()
        campo_senha.send_keys("sua_senha_teste")
        print("Senha preenchida.")

        botao_login = navegador.find_element(By.ID, "dologin")
        botao_login.click()
        print("Botão de login clicado.")
        time.sleep(5) # Aguarda o processo de login

    except Exception as e:
        print(f"Não foi possível encontrar ou interagir com o iframe de login: {e}")

finally:
    # Sempre retornar ao conteúdo padrão após interagir com iframes
    navegador.switch_to.default_content()
    print("Foco retornado para o conteúdo padrão da página.")
    navegador.quit()

Alternando Entre Múltiplas Janelas/Abas

Quando um clique abre uma nova janela ou aba do navegador, o foco do Selenium permanece na janela original. Para interagir com o novo contexto, é preciso alternar o foco para ele.

Método/Propriedade Descrição
current_window_handle Retorna o identificador (handle) da janela/aba atual.
window_handles Retorna uma lista de todos os identificadores de janelas/abas abertas pela sessão atual.
switch_to.window(window_handle) Muda o foco do WebDriver para a janela/aba com o identificador especificado.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)
navegador.get("https://www.google.com")
time.sleep(2)

try:
    # Salva o identificador da janela principal
    janela_inicial = navegador.current_window_handle
    print(f"Identificador da janela principal: {janela_inicial}")

    # Clica em um link que abre uma nova janela/aba
    # Exemplo: um link de "Entrar" que pode levar a um formulário de cadastro em nova aba
    try:
        link_entrar = navegador.find_element(By.LINK_TEXT, "Entrar")
        link_entrar.click()
        time.sleep(2)
        
        # Localiza um link que abre uma nova aba, por exemplo "Criar conta"
        link_criar_conta = navegador.find_element(By.LINK_TEXT, "Criar conta")
        link_criar_conta.click()
        time.sleep(3)
        print("Clicou em 'Criar conta', nova aba deve ter aberto.")

    except Exception as e:
        print(f"Não foi possível encontrar o link 'Entrar' ou 'Criar conta': {e}")
        # Se não encontrar, tentar abrir uma URL genérica em nova aba para demonstração
        navegador.execute_script("window.open('https://www.google.com/intl/pt-BR/account/about/');")
        time.sleep(3)


    # Obtém todos os identificadores de janelas abertas
    todos_identificadores = navegador.window_handles
    print(f"Todos os identificadores de janela: {todos_identificadores}")

    # Alterna para a nova janela/aba
    for identificador in todos_identificadores:
        if identificador != janela_inicial:
            navegador.switch_to.window(identificador)
            print(f"Alternado para a nova janela/aba: {identificador}")
            break
    
    # Agora que estamos na nova janela/aba, podemos interagir com seus elementos
    print(f"Título da nova janela: {navegador.title}")
    # Exemplo: tentar preencher um campo de email, se for uma página de cadastro
    try:
        campo_email_nova_janela = navegador.find_element(By.NAME, "Email") # Assumindo um campo de email
        campo_email_nova_janela.send_keys("novo.usuario@exemplo.com")
        print("Campo de email na nova janela preenchido.")
        time.sleep(2)
    except Exception as e:
        print(f"Não foi possível interagir com elementos na nova janela (elemento 'Email' não encontrado): {e}")

    # Para demonstrar, podemos fechar a nova janela e voltar para a original
    navegador.close() # Fecha a janela atual
    navegador.switch_to.window(janela_inicial) # Volta para a janela original
    print(f"Voltado para a janela principal. Título: {navegador.title}")
    time.sleep(2)

finally:
    navegador.quit()

Manipulando Caixas de Alerta JavaScript

Alertas, confirmações e prompts JavaScript são modais que exigem interação do usuário. O Selenium permite lidar com eles através do objeto alert, acessado por switch_to.alert.

Método Descrição
text Retorna o texto da caixa de alerta.
accept() Aceita (clica em 'OK') o alerta/confirmação.
dismiss() Descarta (clica em 'Cancelar') o alerta/confirmação.
send_keys(keysToSend) Envia texto para um prompt JavaScript.
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)
navegador.get("https://www.google.com") # Usaremos um script para gerar o alerta
time.sleep(2)

try:
    # Gerar um alerta JavaScript para demonstração
    navegador.execute_script("window.alert('Este é um alerta de teste!');")
    time.sleep(2)

    alerta = navegador.switch_to.alert
    print(f"Texto do alerta: {alerta.text}")
    alerta.accept() # Clica em OK
    print("Alerta aceito.")
    time.sleep(2)

    # Gerar um prompt JavaScript
    navegador.execute_script("window.prompt('Por favor, digite seu nome:', 'Visitante');")
    time.sleep(2)

    prompt = navegador.switch_to.alert
    print(f"Texto do prompt: {prompt.text}")
    prompt.send_keys("Automador") # Digita no prompt
    prompt.accept()
    print("Prompt preenchido e aceito.")
    time.sleep(2)

    # Gerar uma confirmação JavaScript
    navegador.execute_script("window.confirm('Você realmente quer continuar?');")
    time.sleep(2)
    
    confirmacao = navegador.switch_to.alert
    print(f"Texto da confirmação: {confirmacao.text}")
    confirmacao.dismiss() # Clica em Cancelar
    print("Confirmação descartada.")
    time.sleep(2)

finally:
    navegador.quit()

Seleção em Dropdowns (Select)

Para interagir com elementos <select> (dropdowns), o Selenium oferece a classe Select, que encapsula métodos para selecionar opções de forma fácil e robusta.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)

# Abrir uma página de teste que contenha um dropdown para demonstração
# Criaremos uma página simples via data URI para este exemplo
pagina_html_dropdown = """

<html>
<head><title>Teste Dropdown</title></head>
<body>
  <h1>Exemplo de Dropdown</h1>
  <select id="opcoes_frutas">
    <option value="apple">Maçã</option>
    <option value="banana">Banana</option>
    <option value="orange">Laranja</option>
    <option value="grape">Uva</option>
  </select>
</body>
</html>
"""
navegador.get(f"data:text/html,{pagina_html_dropdown}")
time.sleep(2)

try:
    dropdown_elemento = navegador.find_element(By.ID, "opcoes_frutas")
    selector = Select(dropdown_elemento)

    print("Opções disponíveis no dropdown:")
    for opt in selector.options:
        print(f"- {opt.text} (value: {opt.get_attribute('value')})")

    # Selecionar por valor (value)
    selector.select_by_value("banana")
    print("Selecionado 'Banana' por valor.")
    time.sleep(2)
    print(f"Opção atualmente selecionada: {selector.first_selected_option.text}")

    # Selecionar por índice (index, começando do 0)
    selector.select_by_index(0) # Maçã
    print("Selecionado 'Maçã' por índice (0).")
    time.sleep(2)
    print(f"Opção atualmente selecionada: {selector.first_selected_option.text}")

    # Selecionar por texto visível
    selector.select_by_visible_text("Laranja")
    print("Selecionado 'Laranja' por texto visível.")
    time.sleep(2)
    print(f"Opção atualmente selecionada: {selector.first_selected_option.text}")

finally:
    navegador.quit()

Upload de Arquivos

Para campos de upload de arquivos (<input type="file">), o Selenium trata-os como campos de texto. Basta usar send_keys() com o caminho completo do arquivo local que você deseja enviar.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import os
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)

# Criar um arquivo de teste e uma página HTML para upload
nome_arquivo_teste = "arquivo_upload_demo.txt"
with open(nome_arquivo_teste, "w") as f:
    f.write("Conteúdo para upload de teste.")

caminho_arquivo_local = os.path.abspath(nome_arquivo_teste)
print(f"Caminho do arquivo de teste: {caminho_arquivo_local}")

pagina_html_upload = f"""

<html>
<head><title>Teste de Upload</title></head>
<body>
  <h1>Upload de Arquivo</h1>
  <form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" id="campo_upload" name="minha_foto"><br><br>
    <input type="submit" value="Enviar Arquivo">
  </form>
</body>
</html>
"""
navegador.get(f"data:text/html,{pagina_html_upload}")
time.sleep(2)

try:
    campo_upload = navegador.find_element(By.ID, "campo_upload")
    print(f"Elemento de upload encontrado. Tentando enviar: {caminho_arquivo_local}")
    
    campo_upload.send_keys(caminho_arquivo_local)
    print("Arquivo enviado para o campo de upload.")
    time.sleep(3) # Tempo para observar o nome do arquivo aparecer no campo (se o navegador o mostrar)

    # O submit do formulário aqui não vai a lugar nenhum real, pois é um data URI.
    # Em um cenário real, você clicaria no botão de submit ou o form seria enviado automaticamente.
    # botao_enviar = navegador.find_element(By.CSS_SELECTOR, "input[type='submit']")
    # botao_enviar.click()
    # print("Botão 'Enviar Arquivo' clicado.")
    # time.sleep(3)

finally:
    navegador.quit()
    # Limpar o arquivo de teste
    if os.path.exists(nome_arquivo_teste):
        os.remove(nome_arquivo_teste)
        print(f"Arquivo de teste '{nome_arquivo_teste}' removido.")

Manipulação de Cookies

O Selenium permite ler, adicionar e excluir cookies do navegador, o que é útil para testes de sessão, personalização ou validação de funcionalidades que dependem de cookies.

Método Descrição
get_cookies() Retorna uma lista de dicionários, onde cada dicionário representa um cookie.
get_cookie(name) Retorna o dicionário do cookie com o name especificado, ou None se não for encontrado.
add_cookie(cookie_dict) Adiciona um cookie. cookie_dict deve ser um dicionário com chaves como 'name', 'value', 'domain', 'path', 'expiry', etc. 'name' e 'value' são obrigatórios.
delete_cookie(name) Exclui o cookie com o name especificado.
delete_all_cookies() Exclui todos os cookies do domínio atual.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)
navegador.get("https://www.google.com") # Um site simples para manipular cookies
time.sleep(2)

try:
    print("=== Cookies Iniciais ===")
    cookies_iniciais = navegador.get_cookies()
    for cookie in cookies_iniciais:
        print(f"Nome: {cookie['name']}, Valor: {cookie['value']}, Domínio: {cookie['domain']}")

    # Adicionar um novo cookie
    novo_cookie = {'name': 'meuCookieTeste', 'value': 'valorDoTeste', 'domain': '.google.com', 'path': '/'}
    navegador.add_cookie(novo_cookie)
    print("\nCookie 'meuCookieTeste' adicionado.")
    time.sleep(1)

    print("\n=== Cookies Após Adição ===")
    cookies_apos_adicao = navegador.get_cookies()
    for cookie in cookies_apos_adicao:
        print(f"Nome: {cookie['name']}, Valor: {cookie['value']}, Domínio: {cookie['domain']}")

    # Obter um cookie específico
    cookie_especifico = navegador.get_cookie('meuCookieTeste')
    if cookie_especifico:
        print(f"\nCookie 'meuCookieTeste' obtido: {cookie_especifico['value']}")

    # Deletar um cookie específico
    navegador.delete_cookie('meuCookieTeste')
    print("\nCookie 'meuCookieTeste' deletado.")
    time.sleep(1)

    print("\n=== Cookies Após Deletar Um ===")
    cookies_apos_deletar_um = navegador.get_cookies()
    for cookie in cookies_apos_deletar_um:
        print(f"Nome: {cookie['name']}, Valor: {cookie['value']}, Domínio: {cookie['domain']}")
    
    # Deletar todos os cookies
    navegador.delete_all_cookies()
    print("\nTodos os cookies deletados.")
    time.sleep(1)

    print("\n=== Cookies Após Deletar Todos ===")
    cookies_apos_deletar_todos = navegador.get_cookies()
    if not cookies_apos_deletar_todos:
        print("Nenhum cookie restante.")
    else:
        for cookie in cookies_apos_deletar_todos:
            print(f"Nome: {cookie['name']}, Valor: {cookie['value']}, Domínio: {cookie['domain']}")

finally:
    navegador.quit()

Execução de Código JavaScript

Para interagir com elementos ou comportamentos da página que não são diretamente acessíveis via API do Selenium (como rolar a barra de rolagem, manipular elementos DOM complexos, ou chamar funções JavaScript), você pode usar o método execute_script().

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.set_window_size(800, 600) # Define um tamanho fixo para garantir barras de rolagem
navegador.get("https://www.w3schools.com/jsref/prop_win_scrolly.asp") # Uma página longa para rolar
time.sleep(3)

try:
    print("URL atual:", navegador.current_url)

    # Rolar para baixo 500 pixels verticalmente
    print("Rolando 500 pixels para baixo...")
    navegador.execute_script("window.scrollBy(0, 500);")
    time.sleep(3)

    # Rolar para o final da página
    print("Rolando para o final da página...")
    navegador.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(3)

    # Rolar para o topo da página
    print("Rolando para o topo da página...")
    navegador.execute_script("window.scrollTo(0, 0);")
    time.sleep(3)

    # Injetar e executar um script para mudar o estilo de um elemento (exemplo)
    try:
        elemento_titulo = navegador.find_element(By.XPATH, "//h1[contains(text(), 'Window scrollY')]")
        navegador.execute_script("arguments[0].style.backgroundColor = 'yellow';", elemento_titulo)
        print("Fundo do título alterado para amarelo via JS.")
        time.sleep(2)
    except Exception as e:
        print(f"Não foi possível alterar o estilo do título via JS: {e}")

finally:
    navegador.quit()

Captura de Tela (Screenshots)

Quando ocorrem falhas em testes automatizados, uma imagem da tela pode ser inestimável para depuração. O Selenium oferece o método get_screenshot_as_file() para capturar a tela do navegador.

Método Descrição
get_screenshot_as_file(filename) Captura uma imagem da janela atual do navegador e salva-a no caminho especificado por filename. Retorna True em caso de sucesso, False caso contrário.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import os
import time

servico = ChromeService(ChromeDriverManager().install())
navegador = webdriver.Chrome(service=servico)
navegador.implicitly_wait(10)
navegador.get("https://www.google.com")
time.sleep(2)

try:
    campo_pesquisa = navegador.find_element(By.NAME, "q")
    campo_pesquisa.send_keys("Selenium Screenshot")
    campo_pesquisa.submit() # Submete o formulário de busca
    time.sleep(3)

    # Definir o caminho para salvar o screenshot
    diretorio_screenshots = "screenshots"
    if not os.path.exists(diretorio_screenshots):
        os.makedirs(diretorio_screenshots)
        print(f"Diretório '{diretorio_screenshots}' criado.")

    nome_arquivo_screenshot = os.path.join(diretorio_screenshots, "google_search_resultado.png")
    
    if navegador.get_screenshot_as_file(nome_arquivo_screenshot):
        print(f"Screenshot salvo com sucesso em: {nome_arquivo_screenshot}")
    else:
        print("Falha ao salvar o screenshot.")

finally:
    navegador.quit()

Encerrando o Navegador

É fundamental fechar o navegador e encerrar o driver após a execução dos testes para liberar recursos do sistema.

Método Descrição
close() Fecha a janela ou aba atualmente focada pelo WebDriver. Se for a última janela, também encerra o driver.
quit() Encerra o processo do WebDriver e fecha todas as janelas/abas associadas à sessão atual. É o método preferido para finalizar um teste.

O método quit() é geralmente usado ao final de todos os testes ou scripts, garantindo que nenhum processo do navegador ou driver permaneça ativo em segundo plano.

Tags: Selenium Python AutomaçãoWeb WebDriver TestesAutomatizados

Publicado em 6-25 16:54