如何使用Python Playwright填充问卷1.1节的数字输入框
Playwright填充Kobotoolbox问卷数字输入框解决方案
问题背景
使用Python+Playwright编写自动填问卷脚本时,前序步骤(密码、季度、选项选择)可正常执行,但无法填充1.1节的6个数字输入框(3个「NO. OF MEN」、3个「NO. OF WOMEN」)。此前尝试用page.get_by_role('number', name='xxx')定位无效。
原因分析
Playwright中,数字输入框的role属性是textbox而非number;且get_by_role的name参数匹配的是元素的标签文本或aria属性,不是HTML的name属性,因此之前的定位逻辑错误。
可行解决方案
方案1:通过HTML的name属性定位(最可靠)
利用输入框唯一的name属性直接定位,fill方法需传入字符串类型的数值:
# 单个输入框示例 await page.locator('input[name="/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m1"]').fill("12")
为简化代码,可将所有输入框的name和对应值整理为列表循环填充:
# 定义所有输入框的name与对应填充值 input_fields = [ ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m1", "12"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m2", "15"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m3", "8"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_women_w1", "10"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_women_w2", "13"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_women_w3", "7"), ] # 循环填充 for name, value in input_fields: await page.locator(f'input[name="{name}"]').fill(value)
方案2:通过标签文本定位
若不想使用冗长的name属性,可通过输入框对应的标签文本(如「NO. OF MEN:」)定位,用nth()区分同标签的多个输入框:
# 填充男性数量输入框 await page.get_by_label("NO. OF MEN:").nth(0).fill("12") await page.get_by_label("NO. OF MEN:").nth(1).fill("15") await page.get_by_label("NO. OF MEN:").nth(2).fill("8") # 填充女性数量输入框 await page.get_by_label("NO. OF WOMEN:").nth(0).fill("10") await page.get_by_label("NO. OF WOMEN:").nth(1).fill("13") await page.get_by_label("NO. OF WOMEN:").nth(2).fill("7")
完整脚本示例
import asyncio from playwright.async_api import async_playwright async def form_entry(): async with async_playwright() as pw: browser = await pw.chromium.launch( headless=False ) page = await browser.new_page() await page.goto('https://ee.kobotoolbox.org/x/cmKGMgos') await page.wait_for_timeout(3000) await page.get_by_label("ENTER YOUR PASSWORD:").fill("123") await page.get_by_label('Q4 (Oct-Nov)').check() await page.get_by_label('A').check() # 填充1.1节的6个数字输入框 input_fields = [ ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m1", "12"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m2", "15"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_men_m3", "8"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_women_w1", "10"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_women_w2", "13"), ("/a8v6GUnyWqGLNQoNqnNkps/level_1/level_1_1/cc_1a_num_women_w3", "7"), ] for name, value in input_fields: await page.locator(f'input[name="{name}"]').fill(value) await browser.close() if __name__ == '__main__': asyncio.run(form_entry())
内容的提问来源于stack exchange,提问作者Chris Browne
相关产品推荐
相关产品推荐

