ฉันจะหาองค์ประกอบโดยคลาส CSS ด้วย XPath ได้อย่างไร


297

ในหน้าเว็บของฉันมีความdivพร้อมกับการตั้งชื่อclassTest

ฉันจะหามันเจอได้XPathอย่างไร?



XPath ที่เกี่ยวข้องทั่วไปมากขึ้น, CSS, DOM และซีลีเนียมโซลูชั่นที่สามารถพบได้ในเอกสารXPath, CSS, DOM และซีลีเนียมที่: Rosetta Stone โดยเฉพาะคำตอบของคุณสามารถพบได้ในรายการId และชื่อ
Terence Xie

คำตอบ:


472

ตัวเลือกนี้ควรใช้งานได้ แต่จะมีประสิทธิภาพมากกว่าหากคุณแทนที่ด้วยมาร์คอัปที่เหมาะสม:

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

หรือเนื่องจากเรารู้ว่าองค์ประกอบที่ต้องการคือ div :

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

แต่เนื่องจากจะตรงกับกรณีเช่นclass="Testvalue"หรือclass="newTest"รุ่นของ @ Tomalak ที่ให้ไว้ในความคิดเห็นนั้นดีกว่า :

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

หากคุณต้องการแน่ใจว่ามันจะจับคู่อย่างถูกต้องคุณสามารถใช้ฟังก์ชั่นการเว้นวรรคเพื่อล้างอักขระช่องว่างว่างรอบชื่อคลาส (ดังที่ @Terry) พูดถึง:

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

โปรดทราบว่าในทุกเวอร์ชันเหล่านี้ควรแทนที่ * ด้วยชื่อองค์ประกอบใด ๆ ที่คุณต้องการจับคู่จริงๆยกเว้นว่าคุณต้องการค้นหาแต่ละองค์ประกอบในเอกสารสำหรับเงื่อนไขที่กำหนด


37
@meder: ชอบมากขึ้น//div[contains(concat(' ', @class, ' '), ' Test ')]- คุณจะเปิดการแข่งขันบางส่วนเช่นกัน
Tomalak

5
ทำไมคุณไม่ลอง // div [@ class = 'Test']
Jessica

11
เนื่องจากคลาสสามารถมีค่ามากกว่าหนึ่งค่า
meder omuraliev

8
ฉันประหลาดใจที่ xpath ไม่มีทางลัด / วิธีที่มีประสิทธิภาพมากขึ้นในการค้นหาโทเค็นในรายการโทเค็นที่คั่นด้วยช่องว่าง มีอะไรใน xpath รุ่นที่ใหม่กว่า?
thomasrutter

1
@thomasrutter เหตุใดจึงแปลกใจ - นี่เป็นเพียงภาษาที่สร้างขึ้นสำหรับ XML ไม่ใช่ HTML ที่เฉพาะเจาะจงยิ่งขึ้นและใครที่จะกล่าวว่าเป็นเรื่องง่ายที่จะใช้รายการที่คั่นด้วยช่องว่างเป็นค่าโหนดใด ๆ ใน XML วิธีแก้ปัญหาของโทมาลักนั้นเป็นสิ่งที่มีประสิทธิภาพมาก
bitoolean

152

วิธีที่ง่ายที่สุด ..

//div[@class="Test"]

สมมติว่าคุณต้องการค้นหา<div class="Test">ตามที่อธิบายไว้


3
ไวยากรณ์ข้างต้นนั้นใช้งานง่ายกว่ามากและมีข้อผิดพลาดน้อยกว่า จำไว้ว่าคุณต้องมีสองเท่ารอบ ๆ ชั้นเพื่อค้นหา ฉันจะแนะนำให้ใช้รายการด้านบน // div [@ class = "Test"]
FlyingV

ใช้งานได้กับกรณีที่ div [class = 'Test'] อยู่ในระดับที่ลึกกว่าหรือไม่
Jake0x32

1
@ Jake0x32 ว่าเป็นเพราะมันใช้ไม่ได้เป็นเพียง// /
โซโลมอน Ucko

7
มันตรงกับ `<div class =" ทดสอบคนอื่น - คลาส "> ด้วยหรือไม่
Jugal Thakkar

11
@JunkThakkar ไม่มันไม่ได้ มันต้องการการทำงานที่ตรงกัน แต่คุณสามารถลอง // div [ประกอบด้วย (@class, "Test")] แทน
Olli Puljula

29

เฉพาะวิธีการที่เหมาะสมที่จะทำกับ XPath:

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

ฟังก์ชั่นตัดnormalize-spaceช่องว่างนำหน้าและต่อท้ายช่องว่างและยังแทนที่ลำดับของอักขระช่องว่างด้วยช่องว่างเดียว


บันทึก

หากไม่ต้องการแบบสอบถาม Xpath เหล่านี้จำนวนมากคุณอาจต้องการใช้ไลบรารีที่แปลงตัวเลือก CSS เป็น XPath เนื่องจากตัวเลือก CSS มักจะง่ายกว่าทั้งในการอ่านและเขียนมากกว่าแบบสอบถาม XPath ตัวอย่างเช่นในกรณีนี้คุณสามารถใช้ทั้งสองdiv[class~="Test"]และdiv.Testเพื่อให้ได้ผลลัพธ์เดียวกัน

ห้องสมุดบางแห่งที่ฉันสามารถหาได้:


24

ฉันแค่ให้คำตอบนี้เป็นคำตอบที่ Tomalak ให้ไว้เพื่อแสดงความคิดเห็นต่อคำตอบของคนกลางเมื่อนานมาแล้ว

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

3
ขออภัยที่จะนำเรื่องนี้ขึ้นจากช่วงเวลาที่ผ่านมา แต่สิ่งที่เกี่ยวกับconcat(' ', normalize-space(@class), ' ')ตัวละครสำหรับพื้นที่สีขาวทุกประเภทเช่นกัน?
เทอร์รี่

เพื่อความอยากรู้อยากเห็น - ทำไม//div[contains(concat(' ', @class, ' '), ' Test ')]/chidไม่เลือกเด็ก?
Fusion

@ ฟิวชั่นถ้าคุณโพสต์คำถามนั้นคุณอาจได้รับคำตอบ
bitoolean

@bitoolean การเป็นกัปตัน Cb ชัดเป็นเรื่องยากในวันนี้
ฟิวชั่น

@ ฟิวชั่นฉันแค่พยายามที่จะช่วย XPath ไม่ใช่ภาษาที่ใช้ HTML มันเป็นเรื่องธรรมดามากกว่า XML เท่านั้น ฉันไม่มีประสบการณ์ แต่ฉันคิดว่าคุณคิดว่าคุณสามารถใส่ ID แทนแท็กได้ คุณต้องเลือกค่าของแอตทริบิวต์ "id" ดังนั้นคุณต้องคิดว่าเอกสาร HTML เป็น XML การอภิปรายนอกหัวข้อไม่ได้ช่วยให้ผู้คนค้นพบวิธีแก้ปัญหา
bitoolean

1

ฟังก์ชั่นที่เป็นประโยชน์สามารถทำจากคำตอบก่อนหน้านี้:

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

จากนั้นเพียงแค่เชื่อมการเรียกใช้ฟังก์ชันลงในคิวรีของคุณ


รหัสนั้นใช้ได้กับ PHP เท่านั้น คุณสามารถพูดถึงมันได้
bitoolean

0

การแข่งขันกับหนึ่งในชั้นเรียนที่มีช่องว่าง

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

-6

คุณสามารถค้นหาองค์ประกอบเช่นตัวอย่างนี้ (องค์ประกอบ CSS ทั้งหมด)

private By 
allElementsCss = By.xpath(".//div[@class]");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.