借助selenium实现自动填写问卷星(可上传图片)

概述

某些问卷还需要上传什么宣传图片才能提交,这样的话上一篇文章的代码就需要稍微改造一下了

准备工作

  • selenium库
    selenium
  • ChromeDriver
    chromedriver
  • Xpath语法
    Xpath语法大家可以在平台自行搜索资源学习,这里不展开说

分析问题

分析问卷

我们要实现自动填写问卷首先需要分析一下问卷星平台生成的问卷

测试问卷展示

测试问卷
问卷星平台要自动生成问卷应该是要有一定生成规则,基于此猜想我们进入开发者模式分析一下网页结构

问卷页面结构分析

如下图所示:
我们可以看到每个问题都被封装到了一个div盒子里,并且每个div的id规律太明显了,都是div加上这个问题的编号(1, 2, 3, … , n),所以我们可以直接写个for循环加上format就可以生成每个div的id了
问卷网页分析

编写代码

基于以上代码我们就可以编写代码了,基本思想如下:

  • 先打开文件网页
    1、判断是否是开放状态
    是则计算开放还剩多少秒输出到控制台,时间到了后点击开始填写问卷
    否则直接开始填写问卷
  • 填写问卷
    写一个for循环来枚举每个div的id,然后获取到问题的标题
    如果是上传图片则直接上传文件,等待2秒后进入下一个循环
    否则根据ID定位问题的输入框然后在定义的dict中拿出对应的数据填写
  • 提交文件

代码

import time
from selenium import webdriver
import re
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.chrome.service import Service


def calc(time_str):
    match = re.search(r"(\d+)天(\d+)时(\d+)分(\d+)秒", time_str)
    # 如果匹配成功
    if match:
        days, hours, minutes, seconds = map(int, match.groups())
        # 计算总秒数
        total_seconds = days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds
    else:
        # 如果匹配失败,可以设置一个默认值或抛出异常
        total_seconds = None
    return total_seconds


# TODO 这里记得及时更新对应版本的driver
# 初始化浏览器驱动,这里填入你的chromedriver.exe的存放的绝对路径(从磁盘开始写)
# 指定chromedriver的路径
# 谷歌浏览器driver r"D:\ChromeDriver\chromedriver-win64\chromedriver-win64\chromedriver.exe"
# edge浏览器driver r"D:\EdgeDriver\edgedriver_win64\msedgedriver.exe"
chrome_driver_path = r"D:\ChromeDriver127\chromedriver136-win64\chromedriver-win64\chromedriver.exe"
# 使用Service对象
service = Service(executable_path=chrome_driver_path)
# 创建options对象(如果需要设置额外的选项)
options = webdriver.ChromeOptions()
# 或者可以使用其他浏览器的驱动,这里创建浏览器对象
# 初始化driver
browser = webdriver.Chrome(service=service, options=options)
# 准备资源,把可能用到的数据以key: value的形式存入下方字典中
information_dict = {
    "校区": "xx校区",
    "学院": "xx学院",
    "专业": "xxxx",
    "班级": "xxxx",
    "姓名": "spider",
    "学号": "201700707",
    "QQ": "123456789",
    "年级": "2017",
    "性别": "男",
    "手机号": "1123456783",
    "电话": "1123456783",
    "file": r"E:\PythonExperiment\ObjectLearn\images\test.png"
}


def get_key(key_info: str):
    for key_ in information_dict.keys():
        if key_.lower() in key_info.lower():
            return key_


# 打开网页
# TODO 这里填写你要填写的问卷url
url = "https://your url  "
browser.get(url)
try:
    while True:
        try:
            time_waite = calc(browser.find_element(By.XPATH, "//div[@id='divStartTimeTip']").text)
        except NoSuchElementException:
            time_waite = 0
        except:
            continue
        if time_waite > 0:
            print(f"还需等待: {time_waite}秒")
            time.sleep(2)
        if time_waite == 0 or time_waite is None:
            break
    browser.find_element(By.XPATH, "//div[@id='countdownHtml']//a").click()
    time.sleep(2)  # 等待页面打开 可以根据需要自己设置时间
except NoSuchElementException:
    pass

# 填写表单
for index in range(1, 10):
    searchID = f"q{index}"
    try:
        key_info = browser.find_element(By.XPATH, f"//div[@id='div{index}']//div[@class='topichtml']").text
        # 根据Xpath语法获取到第index个问题
        if "图片" in key_info.lower():
            # 说明当前项是需要上传图片的
            upload_button = browser.find_element(By.XPATH, f'//div[@id="div{index}"]//input')  # 获取到输入框
            upload_button.send_keys(information_dict.get("file"))  # 上传图片
            time.sleep(1)  # 等待图片上传完
            continue
        text = browser.find_element(By.ID, searchID)  # 根据ID定位到指定的输入框
        key = get_key(key_info)
        text.send_keys(information_dict.get(key, "x"))  # 没有对应属性时,将填入x
    except Exception as e:
        print(f"Failed to fill in question {index}: {e}")
        break
# 查找并点击按钮
try:
    while True:
        # 点击提交按钮
        button = browser.find_element(By.ID, 'ctlNext')  # 根据ID来定位提交按钮
        if button is not None:
            button.click()  # 点击提交按钮
            break
    # 等待新的元素出现,这表明页面已经成功加载了下一个步骤
    WebDriverWait(browser, 10).until(
        ec.presence_of_element_located((By.ID, 'divdsc'))
    )
    print("Click was successful.")
except Exception as e:
    print(f"Failed to click the button: {e}")

# 关闭浏览器
browser.quit()

效果展示

效果展示

图片资源

我测试用的图片时仙剑三中的白豆腐
霍建华-徐长卿-白豆腐

注意事项

在填写或者等待文件时最好不要将打开的chrome页面最小化或放置到其它界面之后
注意修改TODO部分的内容
如果有任何问题或改进意见欢迎在评论区讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值