Làm cách nào tôi có thể tìm thấy một phần tử theo lớp CSS với XPath?


297

Trong trang web của tôi, có một divcái classtên Test.

Làm thế nào tôi có thể tìm thấy nó với XPath?



Các giải pháp XPath, CSS, DOM và Selenium liên quan tổng quát hơn có thể được tìm thấy trong tài liệu XPath, CSS, DOM và Selenium: The Rosetta Stone . Cụ thể, câu trả lời của bạn có thể được tìm thấy trong mục Id & Name .
Terence Xie

Câu trả lời:


472

Công cụ chọn này sẽ hoạt động nhưng sẽ hiệu quả hơn nếu bạn thay thế nó bằng đánh dấu phù hợp của bạn:

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

Hoặc, vì chúng ta biết yếu tố tìm kiếm là div:

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

Nhưng vì điều này cũng sẽ phù hợp với các trường hợp như class="Testvalue"hoặc class="newTest", phiên bản của @ Tomalak được cung cấp trong các nhận xét sẽ tốt hơn :

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

Nếu bạn muốn thực sự chắc chắn rằng nó sẽ khớp chính xác, bạn cũng có thể sử dụng hàm không gian chuẩn hóa để dọn sạch các ký tự khoảng trắng đi lạc xung quanh tên lớp (như được đề cập bởi @Terry):

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

Lưu ý rằng trong tất cả các phiên bản này, * tốt nhất nên được thay thế bằng bất kỳ tên thành phần nào bạn thực sự muốn khớp, trừ khi bạn muốn tìm kiếm từng phần tử trong tài liệu cho điều kiện đã cho.


37
@meder: Giống hơn //div[contains(concat(' ', @class, ' '), ' Test ')]- Bạn cũng sẽ bật một phần trận đấu.
Tomalak

5
Tại sao bạn không làm // div [@ class = 'Test']
Jessica

11
Bởi vì các lớp có thể chứa nhiều hơn một giá trị
trung gian ometiciev

8
Tôi ngạc nhiên khi xpath không có lối tắt / cách hiệu quả hơn để định vị mã thông báo trong danh sách mã thông báo được phân tách bằng dấu cách. Bất cứ điều gì trong các phiên bản sau của xpath?
thomasrutter

1
@thomasrutter tại sao điều ngạc nhiên - đây chỉ là ngôn ngữ được tạo cho XML, không phải là HTML cụ thể hơn và ai sẽ nói rằng việc sử dụng các danh sách được phân tách bằng không gian như bất kỳ giá trị nút nào trong XML. Giải pháp của Tomalak là một giải pháp rất khả thi.
bitoolean

152

Cách dễ nhất ..

//div[@class="Test"]

Giả sử bạn muốn tìm <div class="Test">như mô tả.


3
Cú pháp trên dễ sử dụng hơn rất nhiều và ít bị lỗi hơn. HÃY NHỚ bạn cần phải có NHỮNG SỐ LƯỢNG NHÂN ĐÔI quanh lớp để tìm kiếm. Tôi sẽ khuyên bạn nên sử dụng các liệt kê ở trên. // div [@ class = "Test"]
FlyingV

Điều này có hoạt động cho các trường hợp div [class = 'Test'] nằm ở cấp độ sâu hơn không?
Jake0x32

1
@ Jake0x32, đó là vì nó //không chỉ sử dụng /.
Solomon Ucko

7
Nó có khớp với `<div class =" Test some-other-class "> không?
Jrif Thakkar

11
@JrifThakkar Không, không. Nó đòi hỏi một kết hợp chính xác để hoạt động nhưng thay vào đó bạn có thể thử // div [chứa (@ class, "Test")].
Olli Puljula

29

Các CHỈ đúng cách để làm điều đó với XPath:

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

Các hàm normalize-spacedải khoảng trắng hàng đầu và dấu kiểm, và cũng thay thế các chuỗi ký tự khoảng trắng bằng một khoảng trắng.


Ghi chú

Nếu không cần nhiều truy vấn Xpath này, bạn có thể muốn sử dụng thư viện chuyển đổi bộ chọn CSS thành XPath, vì bộ chọn CSS thường dễ đọc và ghi hơn truy vấn XPath. Ví dụ, trong trường hợp này, bạn có thể sử dụng cả hai div[class~="Test"]div.Testđể có được kết quả như nhau.

Một số thư viện tôi đã có thể tìm thấy:


24

Tôi chỉ cung cấp câu trả lời này như một câu trả lời, vì Tomalak đã cung cấp như một nhận xét cho câu trả lời của người trung gian từ lâu

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

3
Xin lỗi để đưa điều này lên từ một thời gian trước đây nhưng điều gì concat(' ', normalize-space(@class), ' ')sẽ giải thích cho tất cả các loại nhân vật không gian trắng?
Terry

Vì tò mò - Tại sao //div[contains(concat(' ', @class, ' '), ' Test ')]/chidkhông chọn trẻ em?
Hợp nhất

@Fusion nếu bạn đăng câu hỏi đó, bạn có thể nhận được câu trả lời.
bitoolean

@bitoolean trở thành đội trưởng Cbingly ngày nay thật khó khăn
Fusion

@Fusion Tôi chỉ cố gắng giúp đỡ. XPath không phải là ngôn ngữ nhận biết HTML. Nó chung chung hơn, chỉ dành cho XML. Tôi không có bất kỳ kinh nghiệm nào trong đó, nhưng tôi nghĩ rằng bạn cho rằng bạn chỉ có thể đặt id thay vì thẻ. Bạn cần chọn giá trị của thuộc tính "id". Vì vậy, bạn cần nghĩ về tài liệu HTML là XML. Các cuộc thảo luận ngoài chủ đề không giúp mọi người tìm giải pháp mặc dù.
bitoolean

1

Một chức năng hữu ích có thể được thực hiện từ các câu trả lời trước:

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

Sau đó, chỉ cần nối hàm gọi vào truy vấn của bạn.


Mã đó sẽ chỉ hoạt động trong PHP. Bạn có thể đã đề cập đến nó.
bitoolean

0

Phù hợp với một lớp có khoảng trắng.

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

-6

bạn có thể tìm thấy các phần tử như ví dụ này (tất cả các phần tử css)

private By 
allElementsCss = By.xpath(".//div[@class]");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.