Voltar ao blogue
Casos de utilização
Mihai MaximLast updated on May 1, 202614 min read

Selectores XPath vs CSS: Escolher o correto

Selectores XPath vs CSS: Escolher o correto
Resumo: Tanto o XPath como os seletores CSS localizam elementos do DOM, mas resolvem problemas diferentes. Os seletores CSS são mais rápidos e mais legíveis para seleções simples. O XPath é a melhor opção quando é necessário percorrer o DOM em qualquer direção, corresponder conteúdo de texto ou lidar com lógica condicional complexa. A maioria dos projetos de produção beneficia da utilização estratégica de ambos.

Todos os scripts de web scraping, fluxos de trabalho de automação de navegadores e testes de ponta a ponta partilham um requisito fundamental: encontrar elementos no DOM. A questão da escolha entre seletores XPath e CSS surge logo no início de cada projeto, e escolher a abordagem errada pode significar uma execução mais lenta, localizadores frágeis e uma manutenção complicada.

O XPath (XML Path Language) é uma linguagem de consulta concebida para navegar e selecionar nós em documentos XML e HTML. Os seletores CSS são cadeias de padrões originalmente criadas para estilizar HTML, mas amplamente adotadas para a seleção de elementos em frameworks de testes e scraping. Ambos levam-no aos mesmos elementos, mas o caminho que seguem (e as vantagens e desvantagens ao longo do caminho) diferem significativamente.

Este guia analisa a sintaxe, as características de desempenho, o suporte das estruturas e o comportamento em casos extremos de cada abordagem, para que possa fazer uma escolha segura e informada para o seu projeto.

XPath vs. Seletores CSS em resumo

Tanto o XPath como os seletores CSS identificam elementos dentro de um documento HTML ou XML, mas provêm de mundos diferentes. O XPath foi criado para a navegação em documentos XML e suporta percurso bidirecional, o que significa que pode passar de filho para pai com a mesma facilidade com que passa de pai para filho. Os seletores CSS têm origem nas folhas de estilo e movem-se apenas numa direção: de pai para filho (ou irmão).

Eis o veredicto rápido: se as suas necessidades de seleção forem simples (IDs, classes, atributos, combinadores), os seletores CSS são a escolha mais rápida e legível. Quando precisar de percorrer para cima, corresponder conteúdo de texto ou aplicar filtros condicionais complexos, o XPath é a única opção que o levará até lá.

Dimensão

Seletores CSS

XPath

Direção

Apenas de pai para filho

Bidirecional (qualquer eixo)

Velocidade

Geralmente mais rápido (motor nativo)

Mais lento nos navegadores

Correspondência de texto

Não suportado

text(), contains()

Legibilidade

Conciso, familiar

Verboso, curva mais acentuada

Tipos de documentos

Apenas HTML

HTML e XML

Como funciona o XPath

XPath, abreviatura de XML Path Language, é uma linguagem de expressão para navegar e consultar documentos XML, incluindo HTML. Trata o documento como uma árvore de nós e permite escrever expressões de caminho que selecionam um ou mais desses nós.

Caminhos absolutos vs. relativos. Um XPath absoluto começa na raiz do documento e especifica cada passo: /html/body/div[1]/ul/li[3]. É frágil porque qualquer alteração estrutural o invalida. Um XPath relativo começa com // e corresponde a nós independentemente da sua posição na árvore: //li[@class='active']. Na prática, os caminhos relativos são quase sempre o que se pretende.

Os métodos de eixos são onde o XPath realmente se destaca. Métodos como parent::, ancestor::, following-sibling::, e preceding-sibling:: permitem-lhe mover-se em qualquer direção a partir de um nó de contexto. Por exemplo, //span[@id='price']/parent::div seleciona o pai div de um span, algo que os seletores CSS simplesmente não conseguem fazer.

Funções-chave como contains(), starts-with()e text() adicionam filtragem condicional. Pode localizar um elemento cujo texto visível inclua uma subcadeia (//a[contains(text(), 'Next Page')]) sem depender de atributos de todo.

Uma advertência importante: a maioria dos ambientes de navegador ainda suporta apenas o XPath 1.0, lançado em 1999 pelo W3C. O XPath 2.0 e 3.0 introduziram funcionalidades poderosas como expressões regulares e sistemas de tipos mais ricos, mas raramente as encontrará na automação baseada em navegador. Bibliotecas como a lxml (Python) oferecem suporte ao XPath 2.0, pelo que a versão que obtém depende da sua cadeia de ferramentas.

Como funcionam os seletores CSS

Um seletor CSS é uma sequência de caracteres que identifica elementos HTML com base no nome da tag, ID, classe, atributos, posição ou estado. Originalmente concebidos para aplicar estilos em folhas de estilo, os seletores CSS tornaram-se o método padrão de seleção de elementos na maioria das estruturas modernas de automação e scraping.

Os conceitos básicos são familiares a qualquer programador front-end. #main seleciona um elemento pelo ID. .card corresponde a elementos com uma classe específica. div > p seleciona diretamente p filhos diretos de um div. Seletores de atributos como input[type="email"] e pseudoclasses posicionais como :nth-child(2) permitem restringir ainda mais a sua seleção.

As pseudo-classes modernas estão a colmatar a lacuna em relação ao XPath. O :has() seletor, agora amplamente suportado, permite selecionar um pai com base nos seus filhos: div:has(> img.hero) seleciona qualquer div que contenha diretamente um img com a classe hero. O :is() e :where() pseudoclasses simplificam o agrupamento, e :not() lida com a exclusão. Estas adições significam que os seletores CSS podem lidar com alguns cenários que anteriormente exigiam o XPath.

Dito isto, os seletores CSS não podem selecionar nós de texto diretamente e permanecem limitados à percussão para a frente (de pai para filho). Além disso, só funcionam com documentos HTML; se precisar de consultar XML bruto ou feeds não HTML, o XPath é a sua única opção.

Comparação de sintaxe lado a lado

Ver o XPath e os seletores CSS lado a lado é a forma mais rápida de internalizar as suas diferenças. A tabela abaixo mapeia objetivos de seleção comuns para ambas as sintaxes, visando os mesmos elementos hipotéticos da página.

Objetivo de seleção

Seletor CSS

XPath

Por ID

#username

//*[@id='username']

Por classe

.card

//*[contains(@class,'card')]

Por atributo

a[href^="https"]

//a[starts-with(@href,'https')]

Filho direto

ul > li

//ul/li

N-ésimo filho

li:nth-child(3)

//li[3]

Por conteúdo de texto

Não é possível

//a[text()='Login']

Pai do elemento

div:has(> span.icon) (CSS4)

//span[@class='icon']/parent::div

Irmão seguinte

h2 ~ p

//h2/following-sibling::p

Ancestral

Não é possível

//span/ancestor::form

Algumas coisas saltam à vista. Para seleções de ID, classe e atributos, o CSS é visivelmente mais curto e fácil de ler. Mas assim que se precisa de correspondência de texto ou de percurso de antepassados, o XPath é a única opção disponível. A :has() reduz esta diferença na seleção de pais, mas não consegue substituir o sistema de eixos completo do XPath.

Do ponto de vista da legibilidade, os seletores CSS parecem naturais para qualquer pessoa que já tenha escrito uma folha de estilo. A sintaxe baseada em percursos do XPath é mais prolixa, mas essa prolixidade proporciona precisão para consultas complexas. Se a sua equipa incluir programadores front-end que se sintam à vontade com CSS, eles irão familiarizar-se com os seletores CSS muito mais rapidamente do que com as expressões XPath.

Desempenho e velocidade

A sabedoria convencional é que os seletores CSS são mais rápidos do que o XPath em ambientes de navegador e, na prática, isso geralmente é verdade. Os navegadores incluem motores de seletores CSS nativos altamente otimizados, porque a correspondência CSS é uma parte essencial do pipeline de renderização. A avaliação do XPath, em contrapartida, fica fora desse caminho rápido e normalmente acarreta mais sobrecarga.

Dito isto, não existem benchmarks públicos padronizados e amplamente citados que quantifiquem a diferença exata no desempenho entre o XPath e os seletores CSS. A diferença é real, mas muitas vezes insignificante, a menos que esteja a executar dezenas de milhares de avaliações de seletores por página. Para a maioria dos fluxos de trabalho de scraping e testes, a velocidade do seletor raramente é o gargalo; a latência da rede e a renderização da página dominam o tempo de execução.

Fora do navegador, o panorama muda. Bibliotecas como a lxml compilam expressões XPath em código C otimizado, tornando a avaliação do XPath extremamente rápida para o scraping do lado do servidor em Python. Os utilizadores do Scrapy, por exemplo, podem não notar praticamente nenhuma diferença de velocidade entre os seletores XPath e CSS, uma vez que ambos são avaliados através da lxml nos bastidores.

Filtragem avançada, percurso e legibilidade

A percussão bidirecional do XPath é a sua maior vantagem técnica. Utilizando eixos como parent::, ancestor::, following-sibling::, e preceding-sibling::, pode-se navegar pela árvore DOM em qualquer direção a partir de qualquer nó inicial. Isto é indispensável quando o elemento que precisa de selecionar não possui um atributo único, mas tem uma relação previsível com um irmão ou antepassado que o possui.

Os seletores CSS são apenas unidirecionais. Pode ir de pai para filho (>) ou de um irmão anterior para um posterior (~, +), mas não pode ir para cima. A :has() pseudoclasse é uma solução parcial: permite-lhe selecionar condicionalmente um pai com base nos seus descendentes. Ainda assim, :has() não oferece uma percussão completa dos antepassados, e o seu suporte nos navegadores, embora esteja a crescer, ainda não é universal em ambientes mais antigos.

A seleção de nós de texto é outra vantagem clara do XPath. Expressões como //td[contains(text(), 'Total')] permitem localizar elementos pelo seu conteúdo visível, o que é inestimável para extrair páginas onde os elementos não possuem nenhuma classe ou ID significativa. O CSS não tem equivalente.

A curva de aprendizagem merece uma menção ao avaliar seletores XPath vs. CSS para a sua equipa. Os seletores CSS beneficiam de uma familiaridade generalizada; a maioria dos programadores já os utilizava em folhas de estilo muito antes de se depararem com a automação. As expressões XPath, especialmente aquelas que utilizam múltiplos eixos ou predicados aninhados, acarretam uma carga cognitiva mais elevada. Essa complexidade vale a pena quando é necessária, mas para seleções mais simples é uma sobrecarga desnecessária.

Compatibilidade com frameworks e bibliotecas

Nem todas as estruturas tratam os seletores XPath e CSS da mesma forma. Antes de se comprometer com uma estratégia de seletores, verifique o que a sua cadeia de ferramentas realmente suporta.

Framework / Biblioteca

Seletores CSS

XPath

Selenium (todas as linguagens)

Sim

Sim

Playwright

Sim

Sim

Marionetista

Sim

Sim (através de $x())

Scrapy (Python)

Sim (via parsel)

Sim (via parsel/lxml)

lxml (Python)

Sim (via cssselect)

Sim (nativo)

BeautifulSoup (Python)

Sim

Não (utilize o backend lxml)

Cheerio (Node.js)

Sim

Não

Algumas nuances que vale a pena notar. O Puppeteer expõe o XPath através de um $x() em vez da API de seletor principal $() , pelo que a integração é ligeiramente menos harmoniosa. O BeautifulSoup não inclui um motor XPath integrado; se precisar de XPath com o BeautifulSoup, terá de o combinar com um backend de analisador lxml. O Cheerio foi concebido exclusivamente para CSS.

Para os utilizadores do Selenium que estão a avaliar seletores XPath versus CSS, ambos os tipos são cidadãos de primeira classe através de By.CSS_SELECTOR e By.XPATH. O Playwright suporta ambos de forma semelhante, tornando-o uma boa escolha se pretender a flexibilidade de misturar estratégias de seleção dentro de um único conjunto de testes ou pipeline de análise de dados.

Casos extremos: Shadow DOM, iframes e conteúdo dinâmico

As páginas do mundo real raramente são tão simples como os exemplos dos tutoriais, e a decisão entre XPath e seletores CSS torna-se mais complexa quando o Shadow DOM, iframes e conteúdo injetado dinamicamente entram em cena.

Shadow DOM. Por predefinição, os seletores CSS não conseguem atravessar uma raiz shadow fechada. O Playwright oferece o css=pierce/ prefixo como solução alternativa, mas os motores CSS padrão nos navegadores param na fronteira do shadow. O XPath também não ajuda aqui; não possui qualquer conceito nativo de Shadow DOM. Em ambos os casos, normalmente são necessárias APIs específicas da estrutura (como o locator() com penetração) para aceder a elementos shadow.

Iframes. Nem o XPath nem os seletores CSS atravessam os limites do iframe por si só. Deve primeiro mudar o driver ou o contexto para o documento do iframe (driver.switchTo().frame() no Selenium, frame.contentFrame() no Playwright) e, em seguida, executar o seu seletor dentro desse âmbito.

Conteúdo dinâmico. As aplicações de página única que reescrevem o DOM durante a navegação apresentam um desafio diferente. Os seletores CSS que visam atributos estáveis como data-testid ou aria-label tendem a ser mais resilientes aqui do que os seletores baseados em classes, que podem mudar entre compilações. Expressões XPath ligadas a conteúdo de texto também podem ser fiáveis, desde que o texto visível permaneça consistente.

Escrever seletores resilientes

Independentemente da sua posição em relação aos seletores XPath vs CSS, escrever seletores que sobrevivam às alterações no DOM é mais importante do que a linguagem que escolher. Localizadores frágeis são a principal causa de testes instáveis e scrapers com falhas.

Melhores práticas para ambos os tipos:

  • Dê preferência a atributos estáveis. Use data-testid, aria-labelou outros atributos semânticos em vez de nomes de classe gerados automaticamente ou índices posicionais.
  • Mantenha os seletores curtos. Um seletor CSS como [data-testid="submit-btn"] é mais resiliente do que div.form-wrapper > div:nth-child(3) > button.btn-primary. O mesmo se aplica ao XPath: //button[@data-testid='submit-btn'] é melhor do que um caminho absoluto de cinco níveis.
  • Evite o XPath absoluto. Seletores que começam por /html/body/... deixam de funcionar assim que qualquer elemento pai é alterado. Utilize sempre XPath relativo, começando por //.

Antipadrões comuns a evitar:

  • Encadeamento de mais de três níveis de combinadores descendentes em CSS
  • Usar XPath position() ou seleção baseada em índice (div[4]) quando existe um atributo semântico
  • Depender de nomes de classes gerados dinamicamente (comum em frameworks CSS-in-JS) para qualquer um dos tipos de seletor

Investir numa estratégia de seletores desde o início, escolhendo âncoras estáveis e documentando as suas convenções, poupa tempo significativo de depuração à medida que o seu projeto cresce.

Quando usar XPath, seletores CSS ou ambos

Não há um vencedor universal no debate entre XPath e seletores CSS. A escolha certa depende do que está a construir.

Opte por seletores CSS quando as suas seleções envolverem IDs, classes, atributos ou pseudoclasses posicionais. São mais rápidos nos navegadores, mais fáceis de ler e suportados em todo o lado. Para tarefas simples de web scraping e a maior parte da automação de testes front-end, os seletores CSS satisfazem 80% ou mais das suas necessidades de localização com menos código.

Recorra ao XPath quando precisar de percorrer para cima (seleção de pai ou antepassado), corresponder conteúdo de texto ou aplicar filtros condicionais complexos que encadeiam vários predicados. O XPath é também a melhor escolha ao trabalhar com documentos XML não HTML ou quando os elementos alvo não possuem quaisquer atributos úteis.

Use ambos quando o seu projeto o justificar. No Selenium ou no Playwright, não há qualquer custo em misturar By.CSS_SELECTOR e By.XPATH no mesmo ficheiro de teste. Uma abordagem híbrida permite-lhe usar CSS para as seleções simples e rápidas e o XPath para os poucos casos extremos que o exigem.

Lista de verificação de decisão de referência rápida

Use esta lista de verificação para combinar as restrições do seu projeto com o tipo de seletor certo:

  • A velocidade é a principal prioridade e está a executar num navegador: utilize seletores CSS.
  • Precisa de percorrer elementos pai ou ancestrais: utilize XPath.
  • Precisa de corresponder por conteúdo de texto visível: utilize XPath.
  • A sua estrutura suporta apenas um tipo (por exemplo, o Cheerio é apenas CSS): utilize o que estiver disponível.
  • Está a extrair feeds XML ou dados não HTML: utilize o XPath.
  • A sua equipa é composta principalmente por programadores front-end: opte por seletores CSS para uma integração mais rápida.
  • O DOM muda frequentemente e queres localizadores resilientes: usa o tipo que for mais adequado data-testid ou aria-label (ambos lidam bem com isso).

Pontos-chave

  • Os seletores CSS são geralmente mais rápidos em ambientes de navegador e mais legíveis para seleções padrão (ID, classe, atributo, posicional).
  • O XPath é a única opção quando precisa de percorrer o DOM bidirecionalmente, fazer correspondência de conteúdo de texto ou selecionar antepassados.
  • As pseudoclasses CSS modernas, como :has() estão a reduzir a diferença de capacidades, mas não substituem totalmente o sistema de eixos do XPath.
  • O suporte das frameworks varia: Cheerio e BeautifulSoup (sem lxml) são apenas CSS, enquanto Selenium e Playwright suportam ambos os tipos de seletores de forma igual.
  • Ao comparar seletores XPath e CSS, a decisão mais impactante é escrever seletores resilientes que visem atributos estáveis em vez de localizadores posicionais ou de classes geradas, que são frágeis.

Perguntas frequentes

Posso usar seletores XPath e CSS no mesmo teste do Selenium?

Sim. O Selenium suporta ambos os tipos de seletores através de By.CSS_SELECTOR e By.XPATH, e pode misturá-los livremente num único ficheiro de teste ou mesmo num único método de teste. Não há penalização de desempenho ao alternar entre os dois, por isso utilize o tipo que melhor se adequar a cada pesquisa de elemento individual.

Os seletores CSS modernos, como :has(), substituem o XPath para a seleção de elementos pai?

Parcialmente. A :has() pseudoclasse permite selecionar um elemento pai com base nos seus filhos, o que abrange o cenário mais comum de seleção de pais. No entanto, não suporta a percussão completa de antepassados através de vários níveis, a lógica de irmãos anteriores ou cadeias condicionais que os eixos do XPath permitem. Pense no :has() como cobrindo cerca de 60% dos casos que anteriormente exigiam o XPath para navegação ascendente.

Qual tipo de seletor é mais fiável para aplicações dinâmicas de página única?

Nenhum é inerentemente mais fiável. A fiabilidade depende daquilo a que fixa o seu seletor, não da linguagem do seletor em si. Seletores que visam data-testid ou aria-label atributos permanecem estáveis durante as re-renderizações do framework, independentemente de serem escritos em CSS ou XPath. Evite seletores que dependam de nomes de classes gerados automaticamente ou de índices posicionais profundos.

O XPath é suportado no Puppeteer e no Playwright?

Sim, ambos suportam o XPath. O Puppeteer expõe-no através do $x() método (ou page.evaluate com document.evaluate). O Playwright suporta o XPath nativamente no seu locator() e $() APIs. Em ambas as ferramentas, os seletores CSS são o padrão e os mais utilizados, mas o XPath está disponível quando precisar das suas capacidades de percurso.

Conclusão

A questão do XPath versus seletores CSS não tem uma resposta única, pois são ferramentas complementares que resolvem problemas sobrepostos, mas distintos. Os seletores CSS devem ser a sua escolha padrão por questões de velocidade, legibilidade e simplicidade. O XPath deve ser a sua opção quando se deparar com um impasse na traversal apenas para a frente, precisar de correspondência baseada em texto ou trabalhar com formatos de documentos que não sejam HTML.

A linguagem do seletor importa menos do que a qualidade do seletor. Ancore os seus localizadores em atributos semânticos estáveis. Mantenha-os curtos. Documente as suas convenções para que o próximo programador (ou o seu eu futuro) não tenha de fazer engenharia reversa para perceber por que razão uma expressão XPath específica existe.

Sobre o autor
Mihai Maxim, Desenvolvedor Full Stack @ WebScrapingAPI
Mihai MaximDesenvolvedor Full Stack

Mihai Maxim é um programador Full Stack na WebScrapingAPI, contribuindo em todas as áreas do produto e ajudando a criar ferramentas e funcionalidades fiáveis para a plataforma.

Comece a construir

Pronto para expandir a sua recolha de dados?

Junte-se a mais de 2.000 empresas que utilizam a WebScrapingAPI para extrair dados da Web à escala empresarial, sem quaisquer custos de infraestrutura.