Localização de Elementos
Encontrar elementos em uma página web é a base da automação de navegadores. O Pydoll introduz uma abordagem revolucionária e intuitiva que torna a localização de elementos mais poderosa e fácil de usar do que os métodos tradicionais baseados em seletores.
Por que a Abordagem do Pydoll é Diferente
Ferramentas tradicionais de automação de navegador forçam você a pensar em termos de seletores CSS e expressões XPath desde o início. O Pydoll inverte isso: você descreve o que está procurando usando atributos HTML naturais, e o Pydoll descobre a estratégia de seletor ideal.
# Abordagem tradicional (outras ferramentas)
element = driver.find_element(By.XPATH, "//input[@type='email' and @name='username']")
# Abordagem do Pydoll
element = await tab.find(tag_name="input", type="email", name="username")
Ambos encontram o mesmo elemento, mas a sintaxe do Pydoll é mais clara, mais fácil de manter e menos propensa a erros.
Visão Geral dos Métodos de Localização de Elementos
O Pydoll oferece três abordagens principais para encontrar elementos:
| Método | Usar Quando | Exemplo |
|---|---|---|
find() |
Você sabe os atributos HTML | await tab.find(id="username") |
query() |
Você tem um seletor CSS/XPath | await tab.query("div.content") |
| Travessia | Você quer explorar a partir de um elemento conhecido | await element.get_children_elements() |
flowchart LR
A["Precisa de Elemento?"] --> B{"O que voce tem?"};
B -->|"Atributos HTML"| C["Metodo find()"];
B -->|"CSS/XPath"| D["Metodo query()"];
B -->|"Elemento Pai"| E["Travessia"];
C --> F["WebElement"];
D --> F;
E --> G["Lista de WebElements"];
Análise profunda: Como Funciona
Curioso sobre como o Pydoll implementa a localização de elementos internamente? Confira a documentação FindElements Mixin para aprender sobre a arquitetura, otimizações de desempenho e estratégias internas de seletores.
O Método find(): Seleção Natural de Elementos
O método find() é sua principal ferramenta para localizar elementos. Ele aceita atributos HTML comuns como parâmetros e constrói automaticamente o seletor mais eficiente.
Uso Básico
import asyncio
from pydoll.browser.chromium import Chrome
async def basic_finding():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com')
# Encontrar por ID (mais comum e mais rápido)
username = await tab.find(id="username")
# Encontrar por nome de classe
submit_button = await tab.find(class_name="btn-primary")
# Encontrar por nome de tag
first_paragraph = await tab.find(tag_name="p")
# Encontrar por atributo name
email_field = await tab.find(name="email")
# Encontrar por conteúdo de texto
login_link = await tab.find(text="Login")
asyncio.run(basic_finding())
Combinando Atributos para Precisão
O verdadeiro poder do find() vem da combinação de múltiplos atributos para criar seletores precisos:
import asyncio
from pydoll.browser.chromium import Chrome
async def precise_finding():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/form')
# Combinar nome de tag com tipo
password_input = await tab.find(tag_name="input", type="password")
# Combinar tag, classe e atributos personalizados
submit_button = await tab.find(
tag_name="button",
class_name="btn",
type="submit"
)
# Usar atributos data
product_card = await tab.find(
tag_name="div",
data_testid="product-card",
data_category="electronics"
)
# Combinar múltiplas condições
specific_link = await tab.find(
tag_name="a",
class_name="nav-link",
href="/dashboard"
)
asyncio.run(precise_finding())
Lógica de Combinação: E (AND)
Combinar atributos no find() funciona como uma operação E (AND). O elemento deve corresponder a todos os atributos fornecidos.
Para cenários mais complexos que exigem lógica OU (OR) — como encontrar um elemento que pode ter um id ou um name diferente — a abordagem correta é encadear múltiplas chamadas find(), como demonstrado na seção "Exemplo Completo".
Convenção de Nomenclatura de Atributos
Use underscores para nomes de atributos com hífens. Por exemplo, data-testid se torna data_testid, e aria-label se torna aria_label. O Pydoll os converte automaticamente para o formato correto.
Como o find() Seleciona a Estratégia Ideal
O Pydoll escolhe automaticamente o seletor mais eficiente com base nos atributos que você fornece:
| Atributos Fornecidos | Estratégia Usada | Desempenho |
|---|---|---|
Único: id |
By.ID |
⚡ Mais Rápido |
Único: class_name |
By.CLASS_NAME |
⚡ Rápido |
Único: name |
By.NAME |
⚡ Rápido |
Único: tag_name |
By.TAG_NAME |
⚡ Rápido |
Único: text |
By.XPATH |
⚡ Rápido |
| Múltiplos atributos | Expressão XPath | ✓ Eficiente |
flowchart LR
A["Atributos do find()"] --> B{"Unico ou Multiplo?"};
B -->|"Unico"| C["Seletor Direto"];
B -->|"Multiplo"| D["Construir XPath"];
C --> E["Execucao Rapida"];
D --> E;
Encontrando Múltiplos Elementos
Use find_all=True para obter uma lista de todos os elementos correspondentes:
import asyncio
from pydoll.browser.chromium import Chrome
async def find_multiple():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/products')
# Encontrar todos os cards de produto
products = await tab.find(class_name="product-card", find_all=True)
print(f"Encontrados {len(products)} produtos")
# Encontrar todos os links na navegação
nav_links = await tab.find(
tag_name="a",
class_name="nav-link",
find_all=True
)
# Processar cada elemento
for link in nav_links:
text = await link.text
href = await link.get_attribute("href")
print(f"Link: {text} → {href}")
asyncio.run(find_multiple())
Esperando por Elementos Dinâmicos
Aplicações web modernas carregam conteúdo dinamicamente. Use timeout para esperar que os elementos apareçam:
import asyncio
from pydoll.browser.chromium import Chrome
async def wait_for_elements():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/dashboard')
# Esperar até 10 segundos pelo elemento aparecer
dynamic_content = await tab.find(
class_name="dynamic-content",
timeout=10
)
# Esperar por dados carregados via AJAX
user_profile = await tab.find(
id="user-profile",
timeout=15
)
# Lidar com elementos que podem não aparecer
optional_banner = await tab.find(
class_name="promo-banner",
timeout=3,
raise_exc=False # Retorna None se não encontrado
)
if optional_banner:
await optional_banner.click()
else:
print("Nenhum banner promocional presente")
asyncio.run(wait_for_elements())
Melhores Práticas de Timeout
Use valores de timeout razoáveis. Muito curtos e você perderá elementos de carregamento lento; muito longos e você desperdiçará tempo esperando por elementos que não existem. Comece com 5-10 segundos para a maioria dos conteúdos dinâmicos.
O Método query(): Acesso Direto a Seletores
Para desenvolvedores que preferem seletores tradicionais ou precisam de lógicas de seleção mais complexas, o método query() fornece acesso direto a seletores CSS e expressões XPath.
Seletores CSS
Seletores CSS são rápidos, amplamente compreendidos e perfeitos para a maioria dos casos de uso:
import asyncio
from pydoll.browser.chromium import Chrome
async def css_selector_examples():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com')
# Seletores simples
main_nav = await tab.query("nav.main-menu")
first_article = await tab.query("article:first-child")
# Seletores de atributo
submit_button = await tab.query("button[type='submit']")
required_inputs = await tab.query("input[required]", find_all=True)
# Seletores complexos
nested = await tab.query("div.container > .content .item:nth-child(2)")
# Pseudo-classes
first_enabled_button = await tab.query("button:not([disabled])")
asyncio.run(css_selector_examples())
Expressões XPath
XPath se destaca em relações complexas e correspondência de texto:
import asyncio
from pydoll.browser.chromium import Chrome
async def xpath_examples():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/table')
# Correspondência de texto
button = await tab.query("//button[contains(text(), 'Submit')]")
# Navegar para o pai
input_parent = await tab.query("//input[@name='email']/parent::div")
# Encontrar elementos irmãos
label_input = await tab.query(
"//label[text()='Email:']/following-sibling::input"
)
# Consultas complexas de tabela
edit_button = await tab.query(
"//tr[td[text()='John Doe']]//button[@class='btn-edit']"
)
asyncio.run(xpath_examples())
CSS vs XPath: Qual Usar?
Para um guia completo sobre como escolher entre seletores CSS e XPath, incluindo referências de sintaxe e exemplos do mundo real, veja o Guia de Seletores.
Travessia do DOM: Filhos e Irmãos
Às vezes, você precisa explorar a árvore DOM a partir de um ponto de partida conhecido. O Pydoll fornece métodos dedicados para atravessar relações entre elementos.
Estrutura da Árvore DOM
Entender a estrutura da árvore DOM ajuda a escolher o método de travessia correto:
graph TB
Root[Raiz do Documento]
Root --> Container[div id='container']
Container --> Child1[div class='card']
Container --> Child2[div class='card']
Container --> Child3[div class='card']
Child1 --> GrandChild1[h2 title]
Child1 --> GrandChild2[p description]
Child1 --> GrandChild3[button action]
Child2 --> GrandChild4[h2 title]
Child2 --> GrandChild5[p description]
Child3 --> GrandChild6[h2 title]
Obtendo Elementos Filhos
O método get_children_elements() recupera descendentes de um elemento:
import asyncio
from pydoll.browser.chromium import Chrome
async def traverse_children():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/cards')
# Obter contêiner
container = await tab.find(id="cards-container")
# Obter apenas filhos diretos (max_depth=1)
direct_children = await container.get_children_elements(max_depth=1)
print(f"Contêiner tem {len(direct_children)} filhos diretos")
# Incluir netos (max_depth=2)
descendants = await container.get_children_elements(max_depth=2)
print(f"Encontrados {len(descendants)} elementos até 2 níveis de profundidade")
# Filtrar por nome de tag
links = await container.get_children_elements(
max_depth=3,
tag_filter=["a"]
)
print(f"Encontrados {len(links)} links no contêiner")
# Combinar filtros para elementos específicos
nav_links = await container.get_children_elements(
max_depth=2,
tag_filter=["a", "button"]
)
asyncio.run(traverse_children())
Obtendo Elementos Irmãos
O método get_siblings_elements() encontra elementos no mesmo nível:
import asyncio
from pydoll.browser.chromium import Chrome
async def traverse_siblings():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/list')
# Encontrar item ativo
active_item = await tab.find(class_name="item-active")
# Obter todos os irmãos (excluindo o próprio active_item)
all_siblings = await active_item.get_siblings_elements()
print(f"Item ativo tem {len(all_siblings)} irmãos")
# Filtrar irmãos por tag
link_siblings = await active_item.get_siblings_elements(
tag_filter=["a"]
)
# Processar elementos irmãos
for sibling in all_siblings:
text = await sibling.text
print(f"Irmão: {text}")
asyncio.run(traverse_siblings())
Considerações de Desempenho
A travessia do DOM pode ser cara para árvores grandes. Prefira valores max_depth rasos e parâmetros tag_filter específicos para minimizar o número de nós processados. Para estruturas profundamente aninhadas, considere múltiplas chamadas find() direcionadas em vez de uma única travessia profunda.
Encontrando Elementos Dentro de Elementos
Uma vez que você tem um elemento, pode pesquisar dentro de seu escopo usando os mesmos métodos find() e query().
Importante: Comportamento de Profundidade de Busca
Quando você chama element.find() ou element.query(), o Pydoll busca em TODOS os descendentes (filhos, netos, bisnetos, etc.), não apenas nos filhos diretos. Este é o comportamento padrão do querySelector() e corresponde ao que a maioria dos desenvolvedores espera.
Entendendo o Escopo de Busca
graph TB
Container[div id='container']
Container --> Child1[div class='card' ✓]
Container --> Child2[div class='card' ✓]
Container --> Child3[div class='other']
Child1 --> GrandChild1[div class='card' ✓]
Child1 --> GrandChild2[p class='text']
Child3 --> GrandChild3[div class='card' ✓]
Child3 --> GrandChild4[div class='card' ✓]
# Isso encontra TODOS os 5 elementos com class='card' na árvore
# (2 filhos diretos + 3 descendentes aninhados)
cards = await container.find(class_name="card", find_all=True)
print(len(cards)) # Saída: 5
Busca Básica com Escopo
import asyncio
from pydoll.browser.chromium import Chrome
async def scoped_search():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/products')
# Encontrar um contêiner de produto
product_card = await tab.find(class_name="product-card")
# Pesquisar dentro do card de produto (busca em TODOS os descendentes, retorna apenas a primeira correspondência)
product_title = await product_card.find(class_name="title")
product_price = await product_card.find(class_name="price")
add_button = await product_card.find(tag_name="button", text="Add to Cart")
# Fazer query dentro do escopo
product_image = await product_card.query("img.product-image")
# Encontrar todos os itens dentro de um contêiner (TODOS os descendentes)
nav_menu = await tab.find(class_name="nav-menu")
menu_items = await nav_menu.find(tag_name="li", find_all=True)
print(f"Menu tem {len(menu_items)} itens")
asyncio.run(scoped_search())
Encontrando Apenas Filhos Diretos
Se você precisa encontrar apenas filhos diretos (profundidade 1), use o combinador filho > do CSS ou XPath:
import asyncio
from pydoll.browser.chromium import Chrome
async def direct_children_only():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/cards')
container = await tab.find(id="cards-container")
# Método 1: Combinador filho CSS (>)
# Encontra APENAS filhos diretos com class='card'
direct_cards = await container.query("> .card", find_all=True)
print(f"Filhos diretos: {len(direct_cards)}")
# Método 2: XPath filho direto
direct_divs = await container.query("./div[@class='card']", find_all=True)
# Método 3: Usar get_children_elements() com max_depth=1
# (mas isso filtra apenas por tag, não por outros atributos)
direct_children = await container.get_children_elements(
max_depth=1,
tag_filter=["div"]
)
# Então filtre manualmente por classe
cards_only = [
child for child in direct_children
if 'card' in (await child.get_attribute('class') or '')
]
asyncio.run(direct_children_only())
Comparação: find() vs get_children_elements()
| Funcionalidade | find() / query() |
get_children_elements() |
|---|---|---|
| Profundidade de Busca | TODOS os descendentes | Configurável com max_depth |
| Filtrar Por | Qualquer atributo HTML | Apenas nome da tag |
| Caso de Uso | Encontrar elementos específicos em qualquer lugar na subárvore | Explorar estrutura DOM, obter filhos diretos |
| Desempenho | Otimizado para atributo único | Bom para exploração ampla |
| Parâmetro | tag_name="a" (string) |
tag_filter=["a"] (lista) |
import asyncio
from pydoll.browser.chromium import Chrome
async def comparison_example():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com')
container = await tab.find(id="container")
# Cenário 1: Eu quero TODOS os links em qualquer lugar no contêiner
# Use find() - busca em todos os descendentes
all_links = await container.find(tag_name="a", find_all=True)
# Cenário 2: Eu quero APENAS links filhos diretos
# Use combinador filho CSS
direct_links = await container.query("> a", find_all=True)
# Cenário 3: Eu quero filhos diretos com classe específica
# Use combinador filho CSS
direct_cards = await container.query("> .card", find_all=True)
# Cenário 4: Eu quero explorar a estrutura DOM
# Use get_children_elements()
direct_children = await container.get_children_elements(max_depth=1)
# Cenário 5: Eu quero todos os descendentes até a profundidade 2, filtrados por tag
# Use get_children_elements()
shallow_links = await container.get_children_elements(
max_depth=2,
tag_filter=["a"]
)
asyncio.run(comparison_example())
Quando Usar Cada Método
- Use
find(): Quando você sabe os atributos (classe, id, etc.) e quer pesquisar toda a subárvore - Use
query("> .class"): Quando você precisa apenas de filhos diretos com atributos específicos - Use
get_children_elements(): Ao explorar a estrutura DOM ou filtrar apenas por tag
Casos de Uso Comuns
Essa busca com escopo é incrivelmente útil para trabalhar com padrões repetitivos como:
- Cards de produtos em sites de e-commerce
- Linhas de tabela com múltiplas células
- Seções de formulário com múltiplos campos
- Menus de navegação com itens aninhados
import asyncio
from pydoll.browser.chromium import Chrome
async def practical_example():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/products')
# Encontrar todos os cards de produto na página
product_cards = await tab.find(class_name="product-card", find_all=True)
for card in product_cards:
# Dentro de cada card, encontrar TODOS os descendentes com essas classes
title = await card.find(class_name="product-title")
price = await card.find(class_name="product-price")
# Obter o botão que está em qualquer lugar dentro deste card
buy_button = await card.find(tag_name="button", text="Buy Now")
title_text = await title.text
price_text = await price.text
print(f"Produto: {title_text}, Preço: {price_text}")
# Clicar no botão de compra
await buy_button.click()
asyncio.run(practical_example())
Trabalhando com iFrames
Guia Completo de IFrame Disponível
Esta seção cobre a interação básica com iframe para localização de elementos. Para um guia completo incluindo iframes aninhados, manejo de CAPTCHA, análise técnica profunda e solução de problemas, veja Trabalhando com IFrames.
iFrames apresentam um desafio especial na automação de navegador porque eles têm contextos DOM separados. O Pydoll torna a interação com iframe transparente:
Isolamento de Contexto do iFrame
flowchart TB
subgraph MainPage[Contexto da Pagina Principal]
MainDOM[DOM da Pagina Principal]
IFrameTag[Elemento iFrame]
MainDOM --> IFrameTag
end
subgraph IFrameContext[iFrame - DOM Separado]
IFrameDOM[DOM do iFrame]
IFrameElements[Elementos dentro do iFrame]
IFrameDOM --> IFrameElements
end
IFrameTag -.->|Método get_frame| IFrameContext
MainPage --> MainSearch[tab.find - DOM Principal]
IFrameContext --> IFrameSearch[frame.find - DOM do iFrame]
import asyncio
from pydoll.browser.chromium import Chrome
async def iframe_interaction():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com/page-with-iframe')
# Encontrar o elemento iframe
iframe_element = await tab.query("iframe.embedded-content", timeout=10)
# Obter uma instância de Tab para o conteúdo do iframe
frame = await tab.get_frame(iframe_element)
# Agora use todos os métodos de Tab dentro do contexto do iframe
iframe_button = await frame.find(tag_name="button", class_name="submit")
await iframe_button.click()
iframe_input = await frame.find(id="captcha-input")
await iframe_input.type_text("verification-code")
# Fazer query dentro do iframe
iframe_links = await frame.query("a", find_all=True)
print(f"Encontrados {len(iframe_links)} links no iframe")
asyncio.run(iframe_interaction())
iFrames, Alvos e Capturas de Tela
Ao trabalhar dentro de um iframe, alguns métodos como tab.take_screenshot() não funcionarão porque o CDP do Chrome não pode capturar screenshots de sub-alvos diretamente. Use element.take_screenshot() em vez disso, que funciona dentro de iframes.
Estratégias de Tratamento de Erros
Automação robusta requer o tratamento de casos onde elementos não existem ou demoram mais para aparecer do que o esperado.
Fluxo de Localização de Elemento com Tratamento de Erros
flowchart TB
Start[Iniciar Localizacao de Elemento] --> Immediate[Tentar Localizacao Imediata]
Immediate --> Found1{Elemento Encontrado?}
Found1 -->|Sim| Return1[Retornar WebElement]
Found1 -->|Nao & timeout=0| Check1{raise_exc=True?}
Found1 -->|Nao & timeout>0| Wait[Iniciar Loop de Espera]
Check1 -->|Sim| Error1[Lancar ElementNotFound]
Check1 -->|Nao| ReturnNone[Retornar None]
Wait --> Sleep[Esperar 0.5 segundos]
Sleep --> TryAgain[Tentar Localizar Novamente]
TryAgain --> Found2{Elemento Encontrado?}
Found2 -->|Sim| Return2[Retornar WebElement]
Found2 -->|Nao| TimeCheck{Timeout Excedido?}
TimeCheck -->|Nao| Sleep
TimeCheck -->|Sim| Check2{raise_exc=True?}
Check2 -->|Sim| Error2[Lancar WaitElementTimeout]
Check2 -->|Nao| ReturnNone2[Retornar None]
Usando o Parâmetro raise_exc
Controle se uma exceção deve ser lançada quando elementos não são encontrados:
import asyncio
from pydoll.browser.chromium import Chrome
from pydoll.exceptions import ElementNotFound
async def error_handling():
async with Chrome() as browser:
tab = await browser.start()
await tab.go_to('https://example.com')
# Lançar exceção se não encontrado (comportamento padrão)
try:
critical_element = await tab.find(id="must-exist")
except ElementNotFound:
print("Elemento crítico ausente! Não é possível continuar.")
return
# Retornar None se não encontrado (elementos opcionais)
optional_banner = await tab.find(
class_name="promo-banner",
raise_exc=False
)
if optional_banner:
print("Banner encontrado, fechando-o")
close_button = await optional_banner.find(class_name="close-btn")
await close_button.click()
else:
print("Nenhum banner presente, continuando")
asyncio.run(error_handling())
Melhores Práticas
1. Prefira Seletores Estáveis
Use atributos que têm baixa probabilidade de mudar:
# Bom: Atributos semânticos
await tab.find(id="user-profile") # IDs geralmente são estáveis
await tab.find(data_testid="submit-button") # IDs de teste são feitos para automação
await tab.find(name="username") # Nomes de formulário são estáveis
# Evite: Dependências estruturais
await tab.query("div > div > div:nth-child(3) > input") # Frágil, quebra facilmente
await tab.query("body > div:nth-child(2) > form > div:first-child")
2. Use o Seletor Mais Simples que Funciona
Comece simples e adicione complexidade apenas quando necessário:
# Bom: Simples e claro
await tab.find(id="login-form")
# Desnecessário: Complicado demais
await tab.query("//div[@id='content']/descendant::form[@id='login-form']")
3. Escolha o Método Certo
- Use
find()para buscas simples baseadas em atributos - Use
query()para padrões CSS ou XPath complexos - Use métodos de travessia para explorar a partir de âncoras conhecidas
# Use find() para casos diretos
username = await tab.find(id="username")
# Use query() para padrões complexos
active_nav_link = await tab.query("nav.menu a.active")
# Use travessia para buscas baseadas em relacionamento
container = await tab.find(id="cards")
child_links = await container.get_children_elements(tag_filter=["a"])
4. Adicione Timeouts Significativos
Não use timeouts zero para conteúdo dinâmico, e não espere para sempre por elementos opcionais:
# Bom: Timeouts razoáveis
critical_data = await tab.find(id="data", timeout=10)
optional_popup = await tab.find(class_name="popup", timeout=2, raise_exc=False)
# Ruim: Sem timeout para conteúdo dinâmico
dynamic_element = await tab.find(class_name="ajax-loaded") # Falhará imediatamente
# Ruim: Timeout muito longo para elemento opcional
banner = await tab.find(class_name="ad-banner", timeout=60) # Desperdício de tempo
5. Trate Erros Graciosamente
Planeje para elementos que podem não existir:
# Elementos críticos: deixe as exceções subirem
submit_button = await tab.find(id="submit-btn")
# Elementos opcionais: trate explicitamente
cookie_notice = await tab.find(class_name="cookie-notice", raise_exc=False)
if cookie_notice:
accept_button = await cookie_notice.find(text="Accept")
await accept_button.click()
Exemplo Completo: Automação de Formulário
Aqui está um exemplo completo combinando múltiplas técnicas de localização de elementos:
import asyncio
from pydoll.browser.chromium import Chrome
from pydoll.exceptions import ElementNotFound
async def automate_registration_form():
async with Chrome() as browser:
tab = await browser.start()
try:
# Navegar para a página de registro
await tab.go_to('https://example.com/register', timeout=10)
# Lidar com banner de cookie opcional
cookie_banner = await tab.find(
class_name="cookie-banner",
timeout=2,
raise_exc=False
)
if cookie_banner:
accept = await cookie_banner.find(text="Accept")
await accept.click()
await asyncio.sleep(1)
# Preencher o formulário de registro
# Encontrar campos do formulário
username_field = await tab.find(name="username", timeout=5)
email_field = await tab.find(name="email")
password_field = await tab.find(type="password", name="password")
confirm_password = await tab.find(type="password", name="confirm_password")
# Inserir informações
await username_field.type_text("john_doe_2024", interval=0.1)
await email_field.type_text("john@example.com", interval=0.1)
await password_field.type_text("SecurePass123!", interval=0.1)
await confirm_password.type_text("SecurePass123!", interval=0.1)
# Encontrar e marcar checkbox de termos
# Tentar múltiplas estratégias
terms_checkbox = await tab.find(id="terms", raise_exc=False)
if not terms_checkbox:
terms_checkbox = await tab.find(name="accept_terms", raise_exc=False)
if not terms_checkbox:
terms_checkbox = await tab.query("input[type='checkbox']")
await terms_checkbox.click()
# Encontrar e clicar no botão de envio
submit_button = await tab.find(
tag_name="button",
type="submit",
timeout=2
)
await submit_button.click()
# Esperar por mensagem de sucesso com timeout maior (processamento do formulário)
success_message = await tab.find(
class_name="success-message",
timeout=15
)
message_text = await success_message.text
print(f"Registro bem-sucedido: {message_text}")
# Verificar redirecionamento para o dashboard
await asyncio.sleep(2)
current_url = await tab.current_url
if "dashboard" in current_url:
print("Redirecionado com sucesso para o dashboard")
# Encontrar mensagem de boas-vindas
welcome = await tab.find(class_name="welcome-message", timeout=5)
welcome_text = await welcome.text
print(f"Mensagem de boas-vindas: {welcome_text}")
else:
print(f"URL inesperada após registro: {current_url}")
except ElementNotFound as e:
print(f"Elemento não encontrado: {e}")
# Tirar screenshot para depuração
await tab.take_screenshot("error_screenshot.png")
except Exception as e:
print(f"Erro inesperado: {e}")
await tab.take_screenshot("unexpected_error.png")
asyncio.run(automate_registration_form())
Aprenda Mais
Quer mergulhar mais fundo na localização de elementos?
- Análise aprofundada em FindElements Mixin: Aprenda sobre a arquitetura, estratégias internas de seletores e otimizações de desempenho
- Guia de Seletores: Guia completo de seletores CSS e XPath com referências de sintaxe e exemplos do mundo real
- Domínio WebElement: Entenda o que você pode fazer com os elementos depois de encontrá-los
A localização de elementos é a base para uma automação de navegador bem-sucedida. Domine essas técnicas, e você será capaz de localizar confiavelmente qualquer elemento em qualquer página web, não importa quão complexa seja a estrutura.