如何使用Playwright的get_by_test_id定位元素的直接子元素?
使用Playwright通过test_id定位直接子元素的方法
问题背景
用Playwright做网页测试时,通过id定位器可以用page.locator('#id_tag > div').all()精准获取目标元素的直接子div。但切换到get_by_test_id定位时,page.get_by_test_id("test_id_tag").locator("div").all()会返回所有后代div(包括子元素的子元素等),这是因为该写法等效于locator('#test_id_tag >> div').all(),默认匹配所有后代元素。
最小示例HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <!-- 给目标div加上data-testid属性 --> <div id="id_tag" data-testid="test_id_tag"> <div>level_1 <div>level_1_1 <i>i1_1_1</i> <i>i1_1_2</i> <i>i1_1_3</i> </div> <div>level_1_2 <div>level_1_2_1 <i>level_1_2_1_1</i> </div> <i> level_1_2_2</i> <span>level_1_2_3 </span> </div> </div> <div>level_2 <div>level_2_1 <i>i2_1_1</i> <i>i2_1_2</i> <i>i2_1_3</i> </div> <div>level_2_2 <div>level_2_2_1 <i>level_2_2_1_1</i> </div> <i> level_2_2_2</i> <span>level_2_2_3 </span> </div> </div> <div>level_3 <div>level_3_1 <i>i3_1_1</i> <i>i3_1_2</i> <i>i3_1_3</i> </div> <div>level_3_2 <div>level_3_2_1 <i>level_3_2_1_1</i> </div> <i> level_3_2_2</i> <span>level_3_2_3 </span> </div> </div> </div> </body> </html>
原id定位的代码及预期结果
with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.set_content(html) divs = page.locator('#id_tag > div').all() for el in divs: print(el.inner_text().split('\n')[0]) # 预期输出: # level_1 # level_2 # level_3 browser.close()
解决方案
有两种可靠方法可以通过get_by_test_id仅获取直接子元素:
方法1:使用CSS直接子元素选择器
在locator中使用> div语法,明确指定只匹配当前元素的直接子div:
page.get_by_test_id("test_id_tag").locator("> div").all()
方法2:使用XPath的child轴
通过XPath的child::轴限定只查找直接子元素:
page.get_by_test_id("test_id_tag").locator("xpath=child::div").all()
验证代码
with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.set_content(html) # 任选一种方法即可 divs = page.get_by_test_id("test_id_tag").locator("> div").all() # divs = page.get_by_test_id("test_id_tag").locator("xpath=child::div").all() for el in divs: print(el.inner_text().split('\n')[0]) # 输出结果与id定位一致: # level_1 # level_2 # level_3 browser.close()
内容的提问来源于stack exchange,提问作者Vladimir Malchevskiy
相关产品推荐
相关产品推荐

