Voltar ao Glossario
Glossario Python

Selenium: O que É e Como Funciona | Python Brasil

Aprenda Selenium com Python: automacao de navegador, web scraping dinamico, testes de interface, esperas e boas praticas para interagir com paginas web.

O que e Selenium?

Selenium e uma ferramenta de automacao de navegadores web que permite controlar o Chrome, Firefox, Edge e outros navegadores programaticamente usando Python. Diferente de BeautifulSoup e Requests que trabalham apenas com HTML estatico, Selenium executa JavaScript, interage com elementos dinamicos e simula acoes reais de um usuario — cliques, digitacao, scroll e navegacao.

Selenium e usado em dois cenarios principais: web scraping de sites que dependem de JavaScript para renderizar conteudo e testes automatizados de interfaces web.

Instalacao e Configuracao

# Instalacao
# pip install selenium

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service

# Configuracao basica do Chrome
options = Options()
options.add_argument('--headless')          # sem interface grafica
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--window-size=1920,1080')

# Criar o driver
driver = webdriver.Chrome(options=options)

# Acessar uma pagina
driver.get('https://www.python.org')
print(driver.title)  # 'Welcome to Python.org'

# Fechar o navegador
driver.quit()

Localizando Elementos

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get('https://exemplo.com')

# Por ID
elemento = driver.find_element(By.ID, 'meu-id')

# Por nome de classe
elementos = driver.find_elements(By.CLASS_NAME, 'produto')

# Por tag name
paragrafos = driver.find_elements(By.TAG_NAME, 'p')

# Por name (atributo)
campo = driver.find_element(By.NAME, 'email')

# Por seletor CSS
botao = driver.find_element(By.CSS_SELECTOR, 'button.btn-primary')
itens = driver.find_elements(By.CSS_SELECTOR, 'ul.lista > li')

# Por XPath
titulo = driver.find_element(By.XPATH, '//h1[@class="titulo"]')
links = driver.find_elements(By.XPATH, '//a[contains(@href, "python")]')

# Por texto do link
link = driver.find_element(By.LINK_TEXT, 'Saiba mais')
link_parcial = driver.find_element(By.PARTIAL_LINK_TEXT, 'Saiba')

Interagindo com Elementos

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

driver = webdriver.Chrome()
driver.get('https://exemplo.com/login')

# Digitar texto
campo_email = driver.find_element(By.NAME, 'email')
campo_email.clear()
campo_email.send_keys('usuario@email.com')

campo_senha = driver.find_element(By.NAME, 'senha')
campo_senha.send_keys('minha_senha')

# Clicar em botao
botao_login = driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]')
botao_login.click()

# Teclas especiais
campo_busca = driver.find_element(By.NAME, 'q')
campo_busca.send_keys('Python tutorial')
campo_busca.send_keys(Keys.RETURN)  # pressionar Enter

# Selecionar opcao em dropdown
from selenium.webdriver.support.ui import Select

dropdown = Select(driver.find_element(By.ID, 'estado'))
dropdown.select_by_visible_text('Sao Paulo')
dropdown.select_by_value('SP')
dropdown.select_by_index(0)

# Checkboxes e radio buttons
checkbox = driver.find_element(By.ID, 'aceito-termos')
if not checkbox.is_selected():
    checkbox.click()

Esperas (Waits)

Esperas sao essenciais para lidar com conteudo carregado dinamicamente.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://exemplo.com')

# Espera explicita (recomendada)
wait = WebDriverWait(driver, 10)  # espera ate 10 segundos

# Esperar ate o elemento estar presente no DOM
elemento = wait.until(
    EC.presence_of_element_located((By.ID, 'conteudo-dinamico'))
)

# Esperar ate o elemento estar clicavel
botao = wait.until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, 'button.carregar-mais'))
)
botao.click()

# Esperar ate o texto aparecer
wait.until(
    EC.text_to_be_present_in_element((By.ID, 'status'), 'Carregado')
)

# Esperar ate o elemento desaparecer (loading spinner)
wait.until(
    EC.invisibility_of_element_located((By.CLASS_NAME, 'spinner'))
)

# Espera customizada
def elemento_tem_dados(driver):
    el = driver.find_element(By.ID, 'tabela')
    linhas = el.find_elements(By.TAG_NAME, 'tr')
    return len(linhas) > 1

wait.until(elemento_tem_dados)

Acoes Avancadas

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains

driver = webdriver.Chrome()

# Scroll
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
driver.execute_script('window.scrollBy(0, 500)')

# Scroll ate um elemento
elemento = driver.find_element(By.ID, 'secao-final')
driver.execute_script('arguments[0].scrollIntoView(true);', elemento)

# Hover (passar o mouse)
menu = driver.find_element(By.ID, 'menu-principal')
ActionChains(driver).move_to_element(menu).perform()

# Drag and drop
origem = driver.find_element(By.ID, 'item')
destino = driver.find_element(By.ID, 'area')
ActionChains(driver).drag_and_drop(origem, destino).perform()

# Screenshots
driver.save_screenshot('pagina_completa.png')
elemento.screenshot('elemento.png')

# Executar JavaScript
resultado = driver.execute_script('return document.title')
driver.execute_script('document.getElementById("popup").style.display = "none"')

Web Scraping com Selenium

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv

def scrape_produtos():
    """Coleta produtos de um site com conteudo dinamico."""
    options = Options()
    options.add_argument('--headless')

    driver = webdriver.Chrome(options=options)
    wait = WebDriverWait(driver, 15)

    try:
        driver.get('https://loja.exemplo.com/produtos')

        # Esperar conteudo carregar
        wait.until(EC.presence_of_element_located(
            (By.CSS_SELECTOR, '.card-produto')
        ))

        # Clicar em "Carregar mais" ate nao haver mais
        while True:
            try:
                btn = wait.until(EC.element_to_be_clickable(
                    (By.CSS_SELECTOR, '.btn-carregar-mais')
                ))
                btn.click()
                wait.until(EC.staleness_of(btn))
            except Exception:
                break

        # Extrair dados
        produtos = []
        for card in driver.find_elements(By.CSS_SELECTOR, '.card-produto'):
            nome = card.find_element(By.CSS_SELECTOR, '.nome').text
            preco = card.find_element(By.CSS_SELECTOR, '.preco').text
            produtos.append({'nome': nome, 'preco': preco})

        return produtos

    finally:
        driver.quit()

Erros Comuns

O erro mais frequente e nao usar esperas explicitas, tentando interagir com elementos que ainda nao foram carregados na pagina. Usar time.sleep() em vez de WebDriverWait e uma pratica fragil e lenta. Outro erro e esquecer de chamar driver.quit() ao final, deixando processos do navegador abertos. Tambem e comum nao tratar NoSuchElementException ao buscar elementos que podem nao existir. Nao usar modo headless em ambientes de producao ou CI desperdicaria recursos.

Boas Praticas

Sempre use esperas explicitas com WebDriverWait em vez de time.sleep(). Feche o driver em bloco finally ou use context manager. Use modo headless para scripts automatizados e ambientes de CI. Minimize o numero de interacoes com o navegador — cada acao tem custo de performance. Para sites que nao exigem JavaScript, prefira Requests com BeautifulSoup por ser muito mais rapido.

Quando Usar

Selenium e ideal para sites que dependem de JavaScript para renderizar conteudo, formularios complexos, testes de interface web (end-to-end) e automacao de tarefas repetitivas em navegadores. Para scraping de HTML estatico, BeautifulSoup com Requests e mais eficiente. Como alternativa moderna ao Selenium, considere Playwright, que oferece API mais simples e suporte nativo a async.