Como posso encontrar um elemento pela classe CSS com XPath?


297

Na minha página, há um divcom um classnome Test.

Como posso encontrá-lo XPath?



As soluções XPath, CSS, DOM e Selenium relacionadas mais gerais podem ser encontradas no documento XPath, CSS, DOM e Selenium: The Rosetta Stone . Especificamente, sua resposta pode ser encontrada no item Id & Name .
Terence Xie

Respostas:


472

Esse seletor deve funcionar, mas será mais eficiente se você o substituir pela sua marcação adequada:

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

Ou, já que sabemos que o elemento procurado é um div:

//div[contains(@class, 'Test')]

Mas como isso também corresponderá a casos como class="Testvalue"ou class="newTest", a versão do @ Tomalak fornecida nos comentários é melhor :

//div[contains(concat(' ', @class, ' '), ' Test ')]

Se você deseja ter certeza de que ela corresponderá corretamente, também poderá usar a função normalize-space para limpar caracteres de espaço em branco disperso ao redor do nome da classe (como mencionado por @Terry):

//div[contains(concat(' ', normalize-space(@class), ' '), ' Test ')]

Observe que em todas essas versões, o * deve ser melhor substituído por qualquer nome de elemento que você realmente deseje corresponder, a menos que deseje pesquisar todos os elementos no documento para a condição especificada.


37
@meder: Mais parecido //div[contains(concat(' ', @class, ' '), ' Test ')]- O seu também mostrará correspondências parciais.
21710 Tomalak

5
Por que você simplesmente não faz // div [@ class = 'Test']
Jessica

11
Como as classes podem conter mais de um valor
meder omuraliev

8
Estou surpreso que o xpath não tenha um atalho / maneira mais eficiente de localizar um token em uma lista de token separada por espaço. Alguma coisa nas versões posteriores do xpath?
thomasrutter

1
@thomasrutter por que a surpresa - esta é apenas uma linguagem criada para XML, não o HTML mais específico, e quem pode dizer que é casual usar listas separadas por espaço como qualquer valor de nó em XML. A solução da Tomalak é muito viável.
bitoolean 4/08/19

152

Maneira mais fácil ..

//div[@class="Test"]

Supondo que você deseja encontrar <div class="Test">como descrito.


3
A sintaxe acima é muito mais fácil de usar e menos propensa a erros. Lembre-se de que você precisa ter as CITAÇÕES DUPLAS em torno da classe para pesquisar. Eu recomendaria usar o listado acima. // div [@ class = "Test"]
FlyingV

Isso funciona para os casos em que div [class = 'Test'] está em um nível mais profundo?
Jake0x32

1
@ Jake0x32, é porque usa //não apenas /.
Solomon Ucko

7
Também corresponde a `<div class =" Test some-other-class ">?
Jugal Thakkar

11
@JugalThakkar Não, não. Requer uma correspondência exata para funcionar, mas você pode tentar // div [contains (@class, "Test")].
Olli Puljula

29

A única maneira correta de fazer isso com o XPath:

//div[contains(concat(" ", normalize-space(@class), " "), " Test ")]

A função normalize-spaceremove os espaços em branco à esquerda e à esquerda e também substitui as seqüências de caracteres em branco por um único espaço.


Nota

Se não precisar de muitas dessas consultas Xpath, convém usar uma biblioteca que converta seletores CSS em XPath, pois os seletores CSS geralmente são muito mais fáceis de ler e gravar do que as consultas XPath. Por exemplo, nesse caso, você pode usar os dois div[class~="Test"]e div.Testobter o mesmo resultado.

Algumas bibliotecas que consegui encontrar:


24

Estou apenas fornecendo isso como resposta, pois Tomalak forneceu um comentário à resposta do médico há muito tempo.

//div[contains(concat(' ', @class, ' '), ' Test ')]

3
Desculpe trazer isso à tona há muito tempo, mas que tal também concat(' ', normalize-space(@class), ' ')explica todos os tipos de caracteres de espaço em branco?
Terry

Por uma questão de curiosidade - Por //div[contains(concat(' ', @class, ' '), ' Test ')]/chidque não seleciona crianças?
Fusion

@ Fusion se você postar isso como uma pergunta, poderá obter uma resposta.
bitoolean 4/08/19

@bitoolean sendo capitão Cbvious é difícil nos dias de hoje
Fusão

@ Fusion Eu só estava tentando ajudar. XPath não é uma linguagem compatível com HTML. É mais genérico, somente XML. Não tenho nenhuma experiência nisso, mas acho que você está assumindo que pode colocar o ID em vez da tag. Você precisa selecionar o valor do atributo "id". Então, você precisa pensar no documento HTML como XML. Discussões off-topic não ajudam as pessoas a encontrar soluções.
bitoolean 14/08/19

1

Uma função útil pode ser feita com respostas anteriores:

function matchClass($className) {
    return "[contains(concat(' ', normalize-space(@class), ' '), ' $className ')]";
}

Em seguida, basta concat a chamada de função em sua consulta.


Esse código funcionaria apenas em PHP. Você poderia ter mencionado isso.
bitoolean 4/08/19

0

Combine com uma classe que possui espaço em branco.

<div class="hello "></div>
//div[normalize-space(@class)="hello"]

-6

você pode encontrar elementos como este exemplo (todos os elementos css)

private By 
allElementsCss = By.xpath(".//div[@class]");
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.