影刀RPA 网页表单填写的避坑大全

0 阅读6分钟

影刀RPA 网页表单填写的避坑大全

作者:林焱

什么情况用这个

网页表单填写是影刀自动化中的高频操作——批量提交数据、自动注册账号、填报报表、提交工单。看起来就是拖几个【填写输入框】+【点击提交】,简单得很。但实际上,表单填写的坑多得防不胜防:输入框有格式校验、下拉框不是标准select元素、日期选择器是自定义组件、提交按钮被验证码拦住、填完点提交没反应……

这些坑一个个排查过来,比写采集逻辑还费时间。这篇文章把表单填写中常见的20个问题一次性整理清楚,覆盖输入框、下拉框、复选框、日期选择器、文件上传、提交验证等全场景。 在这里插入图片描述

怎么做

第一步:输入框填写的正确姿势

影刀的【填写输入框】指令在大多数场景下够用,但有几种情况需要特殊处理:

基础用法

【填写输入框】→ 选择输入框元素 → 填入文本

当【填写输入框】不生效时

# 方法1:先清空再输入
input_el = driver.find_element(By.CSS_SELECTOR, "#username")
input_el.clear()                    # 清空原有内容
time.sleep(0.1)
input_el.send_keys("admin")         # 输入新内容

# 方法2:用JavaScript直接设置值(绕过前端校验)
driver.execute_script("""
    var el = document.querySelector('#username');
    el.value = 'admin';
    ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/4efdc5b7922847628a45bf13bc484332~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p6X54SxUlBB:q75.awebp?rk3s=f64ab15b&x-expires=1786434276&x-signature=JQmLgpUVrSugAAAiVhZsfYR%2FpAQ%3D)

    el.dispatchEvent(new Event('input', { bubbles: true }));
""")

# 方法3:逐字输入(触发所有前端事件)
for char in "admin":
    input_el.send_keys(char)
    time.sleep(0.05)

处理只读输入框

# 有些输入框设置了readonly属性
# removeAttribute去掉只读后再操作
driver.execute_script("""
    var el = document.querySelector('#readonly-field');
    el.removeAttribute('readonly');
    
[video(video-QyjI3XuR-1784737505672)(type-csdn)(url-https://live.csdn.net/v/embed/525010)(image-https://v-blog.csdnimg.cn/asset/f4faa587144cb7070f19e8b36813806b/cover/Cover0.jpg)(title-店群矩阵自动化突破运营极限!)]

    el.value = 'new value';
    el.dispatchEvent(new Event('change', { bubbles: true }));
""")

第二步:下拉选择框的处理

下拉框有三种形态,处理方式不同:

标准 <select> 元素

from selenium.webdriver.support.ui import Select

# 方法1:用Select类
select = Select(driver.find_element(By.CSS_SELECTOR, "#province"))
select.select_by_visible_text("广东省")    # 按显示文本选
select.select_by_value("GD")               # 按value选
select.select_by_index(2)                  # 按索引选

# 方法2:获取所有选项
options = select.options
for opt in options:
    print(f"选项: {opt.text} -> {opt.get_attribute('value')}")

自定义下拉框(非标准select,是div+ul模拟的)

在这里插入图片描述

# 这些下拉框的选项是动态生成的,操作流程:
# 1. 点击展开
# 2. 等待选项列表出现
# 3. 选择目标选项

# 展开下拉
driver.find_element(By.CSS_SELECTOR, ".custom-select").click()
time.sleep(0.3)

# 找到并点击目标选项
options = driver.find_elements(By.CSS_SELECTOR, ".dropdown-option")
for opt in options:
    if opt.text.strip() == "目标选项":
        # 滚动到可见
        driver.execute_script("arguments[0].scrollIntoView(true);", opt)
        time.sleep(0.1)
        opt.click()
        break

搜索型下拉框(输入文字过滤选项)

# 先点击 → 输入搜索文字 → 等待过滤出的选项 → 点击
search_input = driver.find_element(By.CSS_SELECTOR, ".search-select input")
search_input.click()
search_input.send_keys("广东")
time.sleep(0.5)
driver.find_element(By.CSS_SELECTOR, ".option-item:first-child").click()

第三步:复选框与单选框

# 复选框
checkbox = driver.find_element(By.CSS_SELECTOR, "#agree")
if not checkbox.is_selected():
    checkbox.click()  # 勾选

# 单选框
radio = driver.find_element(By.CSS_SELECTOR, "input[value='male']")
if not radio.is_selected():
    radio.click()

# 批量勾选(只勾选特定条件的)
checkboxes = driver.find_elements(By.CSS_SELECTOR, ".item-checkbox")
for cb in checkboxes:
    label = cb.find_element(By.XPATH, "../label").text
    if "重要" in label:
        if not cb.is_selected():
            cb.click()

第四步:日期选择器

在这里插入图片描述

日期选择器是表单中的高频难点:

# 策略1:如果输入框可以直接填(最常见的)
date_input = driver.find_element(By.CSS_SELECTOR, "#date")
date_input.clear()
date_input.send_keys("2025-03-15")
# 或 JavaScript 方式
driver.execute_script("arguments[0].value='2025-03-15';", date_input)

# 策略2:如果必须通过日期选择器操作
# 点击打开日期面板 → 选择年/月 → 点击日期
def pick_date(year, month, day):
    """通过日期选择器选择日期"""
    driver.find_element(By.CSS_SELECTOR, "#date-picker").click()
    time.sleep(0.3)
    
    # 选择年份(如果有年份切换)
    year_select = driver.find_element(By.CSS_SELECTOR, ".year-select")
    year_select.click()
    driver.find_element(By.XPATH, f"//*[text()='{year}']").click()
    
    # 选择月份
    month_select = driver.find_element(By.CSS_SELECTOR, ".month-select")
    month_select.click()
    driver.find_element(By.XPATH, f"//*[text()='{month}月']").click()
    
    # 点击具体日期
    driver.find_element(By.XPATH, f"//td[text()='{day}' and not(contains(@class,'other'))]").click()

第五步:文件上传

# 标准文件上传(input type="file")
# 影刀的【上传文件】指令或直接send_keys路径
file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
file_input.send_keys(r"D:\文件\图片.png")  # 绝对路径

# 批量上传(有些支持多文件)
files = [r"D:\图1.png", r"D:\图2.png"]
file_input.send_keys("\n".join(files))

# 非标准上传(拖拽区域或按钮触发)
# 这种情况比较复杂,通常需要发送文件到后端的upload API

第六步:多步骤表单

分步填写的表单(第一步填基本信息→下一步填详情→提交),需要管理填写进度:

在这里插入图片描述

# 分步表单的处理
def fill_step_1():
    driver.find_element(By.CSS_SELECTOR, "#name").send_keys("张三")
    driver.find_element(By.CSS_SELECTOR, "#phone").send_keys("13800138000")
    driver.find_element(By.CSS_SELECTOR, ".next-btn").click()
    wait_element("#step2-form")

def fill_step_2():
    driver.find_element(By.CSS_SELECTOR, "#address").send_keys("广东省深圳市")
    Select(driver.find_element(By.CSS_SELECTOR, "#city")).select_by_visible_text("深圳")
    driver.find_element(By.CSS_SELECTOR, ".next-btn").click()
    wait_element("#step3-form")

def fill_step_3():
    # 最终确认
    driver.find_element(By.CSS_SELECTOR, ".submit-btn").click()

第七步:提交按钮的处理

# 直接点击
submit_btn = driver.find_element(By.CSS_SELECTOR, "#submit")
submit_btn.click()

# 如果点击无效,试试这些方法
# 方法1:JavaScript点击
driver.execute_script("arguments[0].click();", submit_btn)

# 方法2:表单submit
driver.execute_script("document.querySelector('#myForm').submit();")

# 方法3:模拟回车提交
from selenium.webdriver.common.keys import Keys
last_input = driver.find_element(By.CSS_SELECTOR, "#last-field")
last_input.send_keys(Keys.ENTER)

# 检查提交结果
time.sleep(1)
try:
    success_msg = driver.find_element(By.CSS_SELECTOR, ".success-message").text
    print(f"提交成功: {success_msg}")
except:
    try:
        error_msg = driver.find_element(By.CSS_SELECTOR, ".error-message").text
        print(f"提交失败: {error_msg}")
    except:
        print("无法判断提交结果")

有什么坑

坑一:placeholder当作value

现象:有些输入框有灰色的提示文字(placeholder),element.textget_attribute("value") 可能读不到。

在这里插入图片描述

解决

# 获取真正的内容
actual_value = driver.execute_script("return arguments[0].value;", input_el)
# 不要用 element.text

坑二:默认值没清掉

现象:【填写输入框】指令在已有内容的输入框中是"追加"还是"覆盖",你以为是覆盖,结果追加在后面。

解决:填写之前永远先 .clear()

[video(video-aFpStnXH-1784737512292)(type-csdn)(url-live.csdn.net/v/embed/524…)] 在这里插入图片描述

input_el.clear()
time.sleep(0.1)
input_el.send_keys("新内容")

坑三:前端校验触发时机

现象:填到一半就触发了前端校验,弹红色提示挡住了下一个输入框。

解决:填写顺序要和对焦顺序一致(按Tab顺序),不要跳着填。如果校验弹窗挡住了,先关闭弹窗或者用JavaScript绕过校验:

# 暂时禁用HTML5表单校验
driver.execute_script("""
    var form = document.querySelector('form');
    form.setAttribute('novalidate', 'novalidate');
""")

坑四:弹窗拦截点击事件

现象:点提交弹出一个确认框,但流程没有处理,卡住了。

在这里插入图片描述

解决:在提交前注入JavaScript拦截:

# 自动确认所有弹窗
driver.execute_script("""
    window.confirm = function() { return true; };
    window.alert = function() {};
""")

坑五:表单提交后跳转导致的元素失效

现象:提交成功页面跳转后,后续代码引用之前的元素报 StaleElementReferenceException

解决:提交后不要使用之前的任何元素引用,重新获取:

# ❌ 提交后还引用提交前的元素
submit_btn.click()
success_text = element.text  # 报错!这个元素引用已失效

# ✅ 提交后重新定位
![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/344a7a0302f748b7a7f02c4b8fedd3e6~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5p6X54SxUlBB:q75.awebp?rk3s=f64ab15b&x-expires=1786434276&x-signature=Rzfmb2SWOyOCUhcvUvJpqriD6kM%3D)

submit_btn.click()
time.sleep(1)
success_text = driver.find_element(By.CSS_SELECTOR, ".result").text

总结:网页表单的坑,80%来自"你以为它是标准input,其实不是"。遇到填写不生效的情况,先F12看看元素到底是 <input> 还是 <div> 模拟的,有没有 readonlydisabled,值更新了是否触发了 change 事件。别老用【填写输入框】一条指令走到黑——有时候 在这里插入图片描述 send_keysexecute_script 才是正解。