Bagaimana saya bisa menemukan elemen dengan kelas CSS dengan XPath?

297

Di halaman web saya, ada divdengan classnama Test.

Bagaimana saya bisa menemukannya XPath?

Stroberi
sumber
Solusi XPath, CSS, DOM dan Selenium yang lebih umum terkait dapat ditemukan dalam dokumen XPath, CSS, DOM dan Selenium: The Rosetta Stone . Secara khusus, jawaban Anda dapat ditemukan di Id & Nama item .
Terence Xie

Jawaban:

472

Pemilih ini akan berfungsi tetapi akan lebih efisien jika Anda menggantinya dengan markup yang sesuai:

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

Atau, karena kita tahu elemen yang dicari adalah div:

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

Tetapi karena ini juga akan cocok dengan kasus seperti class="Testvalue"atau class="newTest", versi @ Tomalak yang disediakan dalam komentar lebih baik :

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

Jika Anda ingin benar-benar yakin bahwa itu akan cocok dengan benar, Anda juga bisa menggunakan fungsi normalisasi-ruang untuk membersihkan karakter spasi kosong di sekitar nama kelas (seperti disebutkan oleh @Terry):

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

Perhatikan bahwa dalam semua versi ini, * sebaiknya diganti dengan nama elemen apa pun yang sebenarnya ingin Anda cocokkan, kecuali jika Anda ingin mencari setiap elemen dalam dokumen untuk kondisi yang diberikan.

meder omuraliev
sumber
37
@meder: Lainnya seperti //div[contains(concat(' ', @class, ' '), ' Test ')]- Milik Anda juga akan muncul pertandingan parsial.
Tomalak
5
Kenapa kamu tidak melakukan // div [@ class = 'Test']
Jessica
11
Karena kelas dapat berisi lebih dari satu nilai
meder omuraliev
8
Saya terkejut xpath tidak memiliki pintasan / cara yang lebih efisien untuk menemukan token di daftar token yang dipisahkan oleh ruang. Adakah di versi xpath nanti?
thomasrutter
1
@ thomasrutter mengapa kejutannya - ini hanya bahasa yang dibuat untuk XML, bukan HTML yang lebih spesifik, dan siapa yang mengatakan itu biasa untuk menggunakan daftar yang dipisahkan ruang karena setiap nilai simpul dalam XML. Solusi Tomalak sangat bagus.
bitoolean
152

Cara termudah ..

//div[@class="Test"]

Dengan asumsi Anda ingin menemukan <div class="Test">seperti yang dijelaskan.

Olli Puljula
sumber
3
Sintaks di atas jauh lebih mudah digunakan dan lebih rentan kesalahan. INGAT, Anda harus memiliki QUOTLE QUOTES di sekitar kelas untuk mencari. Saya akan merekomendasikan menggunakan yang tercantum di atas. // div [@ class = "Test"]
FlyingV
Apakah ini bekerja untuk kasus-kasus yang div [class = 'Test'] terletak di tingkat yang lebih dalam?
Jake0x32
1
@ Jake0x32, itu karena //tidak hanya menggunakan /.
Solomon Ucko
7
Apakah cocok dengan `<div class =" Test some-other-class "> juga?
Jugal Thakkar
11
@JugalThakkar Tidak, tidak. Ini membutuhkan kecocokan yang tepat untuk bekerja tetapi Anda dapat mencoba // div [berisi (@class, "Test")] sebagai gantinya.
Olli Puljula
29

Cara HANYA yang benar untuk melakukannya dengan XPath:

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

Fungsi normalize-spacestrip memimpin dan mengikuti spasi, dan juga mengganti urutan karakter spasi dengan satu spasi.


Catatan

Jika tidak memerlukan banyak pertanyaan Xpath ini, Anda mungkin ingin menggunakan perpustakaan yang mengubah pemilih CSS ke XPath, karena pemilih CSS biasanya jauh lebih mudah untuk membaca dan menulis daripada permintaan XPath. Misalnya, dalam hal ini, Anda bisa menggunakan keduanya div[class~="Test"]dan div.Testuntuk mendapatkan hasil yang sama.

Beberapa perpustakaan yang dapat saya temukan:

John Slegers
sumber
24

Saya hanya memberikan ini sebagai jawaban, seperti yang diberikan Tomalak sebagai komentar untuk jawaban meder dulu

//div[contains(concat(' ', @class, ' '), ' Test ')]
Alex Lyman
sumber
3
Maaf untuk memunculkan ini dari waktu yang lalu, tetapi bagaimana concat(' ', normalize-space(@class), ' ')dengan menjelaskan semua jenis ruang putih juga?
Terry
Demi rasa ingin tahu - Mengapa //div[contains(concat(' ', @class, ' '), ' Test ')]/chidtidak memilih anak-anak?
Fusion
@Fusion jika Anda mempostingnya sebagai pertanyaan, Anda mungkin mendapatkan jawaban.
bitoolean
@ bitoolean menjadi Kapten Cbvious sulit hari ini
Fusion
@Fusion, saya hanya berusaha membantu. XPath bukan bahasa sadar HTML. Ini lebih umum, hanya XML. Saya tidak punya pengalaman di dalamnya, tapi saya pikir Anda mengasumsikan Anda bisa meletakkan id bukan tag. Anda harus memilih pada nilai atribut "id". Jadi, Anda perlu menganggap dokumen HTML sebagai XML. Diskusi di luar topik tidak membantu orang menemukan solusi.
bitoolean
1

Fungsi yang bermanfaat dapat dibuat dari jawaban sebelumnya:

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

Kemudian, cukup masukkan panggilan fungsi ke dalam kueri Anda.

Carcigenicate
sumber
Kode itu hanya akan berfungsi di PHP. Anda bisa menyebutkannya.
bitoolean
0

Cocokkan dengan satu kelas yang memiliki spasi putih.

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

Anda dapat menemukan elemen seperti contoh ini (semua elemen css)

private By 
allElementsCss = By.xpath(".//div[@class]");
Sergei Zhilinski
sumber