คำตอบสั้น ๆ
นิพจน์ XPath นี้จะค้นหาปุ่มที่มีข้อความ "Button text":
const [button] = await page.$x("//button[contains(., 'Button text')]");
if (button) {
await button.click();
}
หากต้องการเคารพ<div class="elements">
ปุ่มโดยรอบให้ใช้รหัสต่อไปนี้:
const [button] = await page.$x("//div[@class='elements']/button[contains(., 'Button text')]");
คำอธิบาย
เพื่ออธิบายว่าเหตุใดการใช้โหนดข้อความ ( text()
) จึงผิดในบางกรณีลองดูตัวอย่าง:
<div>
<button>Start End</button>
<button>Start <em>Middle</em> End</button>
</div>
ขั้นแรกให้ตรวจสอบผลลัพธ์เมื่อใช้contains(text(), 'Text')
:
//button[contains(text(), 'Start')]
จะส่งคืนทั้งสองโหนด (ตามที่คาดไว้)
//button[contains(text(), 'End')]
จะคืนหนึ่งโหนด (ครั้งแรก) ขณะที่text()
ผลตอบแทนรายการที่มีทั้งสองข้อความ (กStart
และ End
) แต่contains
จะตรวจสอบเฉพาะคนแรก
//button[contains(text(), 'Middle')]
จะไม่ส่งคืนผลลัพธ์เนื่องจากtext()
ไม่มีข้อความของโหนดลูก
นี่คือนิพจน์ XPath สำหรับcontains(., 'Text')
ซึ่งทำงานกับองค์ประกอบเองรวมถึงโหนดลูกด้วย:
//button[contains(., 'Start')]
จะส่งคืนทั้งสองปุ่ม
//button[contains(., 'End')]
จะส่งคืนทั้งสองปุ่มอีกครั้ง
//button[contains(., 'Middle')]
จะส่งคืนหนึ่ง (ปุ่มสุดท้าย)
ดังนั้นในกรณีส่วนใหญ่ควรใช้.
แทนtext()
ในนิพจน์ XPath