问卷星自动填写提交(抢活动专用)

用途:自动抢川农需要填写表单报名的活动,也可根据实际情况修改为其他用途,配合win10计划任务程序使用效果最佳(使用方法请自行百度)。

注意事项:此程序用python编写,需要配置python及安装相应库(所需库见导入模块处),此版本采用pyppeteer模块,无需chromedriver,极大简化了环境的搭建,注意浏览器安装路径改为你的实际安装路径,个人信息填在字典里。如何安装python库请自行百度(实际直接pip install package name即可),pip换源可参考这篇文章:Linux和Windows的pip换源
# encoding=utf8
# 自动填写问卷星表单,适用于全是单项填空的表单,川农登记信息一般为此格式

# 导入所需模块
import time
import asyncio
import os
from pyzbar import pyzbar
from PIL import Image
from pyppeteer import launch
from pyppeteer_stealth import stealth # 反爬虫第三方库
from pyppeteer.errors import PageError # 异常处理


# 识别二维码函数
def decode_qr_code(code_img_path):
  if not os.path.exists(code_img_path):
    raise FileExistsError(code_img_path)
  # Here, set only recognize QR Code and ignore other type of code
  return pyzbar.decode(Image.open(code_img_path), symbols=[pyzbar.ZBarSymbol.QRCODE])


async def main():
  # launch方法会新建一个browser对象,然后赋值给browser
  browser = await launch({
    # 谷歌浏览器的安装路径
    'executablePath': 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
    'headless': False,
    # 设置Windows-size和Viewport大小来实现网页完整显示
    'args': ['--no-sandbox', '--window-size=1366,850'],
    'autoClose': False # 不自动关闭浏览器
  })

  # 调用 newPage 方法相当于浏览器中新建了一个选项卡,同时新建了一个Page对象
  page = await browser.newPage()
  await page.setViewport({'width': 1366, 'height': 768})
  # 防止页面识别出脚本(反爬虫关键语句)
  await stealth(page)

  # 调用了Page对象的goto方法就相当于在浏览器中输入问卷的网址,浏览器跳转到了对应的页面进行加载
  # 从二维码获取问卷链接
  #results = decode_qr_code("s.jpg")
  #url = results[0].data.decode("utf-8")
  url = "https://www.wjx.cn/vj/tqbA2aT.aspx"
  await page.goto(url)
  # 需要填的信息从文件录入
  # with open("./msg.txt", encoding="utf-8") as file:
  #   msg = [data.replace("\n", "") for data in file.readlines() if data != "\n"] # 过滤空行并去掉末尾的换行符
  # file.close()
  # n = len(msg) # 获取需要填写的问题数量
  # 以下为录入常见个人信息,个人报名时使用,无需知晓表单具体内容;多人报名时使用上方方法从文件读入,此时需要提前知晓表单内容
  msg = {
    "姓名": "",
    "学号": "",
    "班级": "",
    "学院": "",
    "专业": "",
    "联系方式": "",
    "手机": "",
    "电话": "",
    "QQ": "",
    "qq": "",
    "邮箱": ""
  }
  # 检查表单是否已开放,还没开放则一直刷新直到开放
  while True:
    elem = await page.querySelector("#q1")
    if not elem:
      await page.goto(url)
    else:
      break
  try:
    await page.click('#slideChunkArrow')
  except PageError:
    pass # 无需滑动则直接pass
  # 用浏览器审查元素,用js找到需填写的信息保存在temp中
  temp = await page.evaluate(pageFunction='''() => {
        temp = document.getElementsByClassName("div_title_question");
        var names = [];
        for (var i = 0; i < temp.length; i++)
          names.push(temp[i].innerHTML);
        return names;
      }''', force_expr=False) # force_expr=False 执行的是函数,True则执行的是语句
  if not temp:  # 使用的是手机制作,类名不一样
    temp = await page.evaluate(pageFunction='''() => {
          temp = document.getElementsByClassName("field-label");
          var names = [];
          for (var i = 0; i < temp.length; i++)
            names.push(temp[i].innerHTML);
          return names;
        }''', force_expr=False) # force_expr=False 执行的是函数,True则执行的是语句
  n = 0
  print("开始自动填写问卷星表单信息...")
  for name in temp:
    for key in msg.keys():
      if key in name: # 匹配机制选择以自己的简洁描述去匹配主办方制作的表单描述,如用"姓名"去匹配"你的姓名"或"您的姓名",显然更实用
        print(name, msg[key])
        await page.type("#q%s" % (n + 1), msg[key])
        n += 1
  print("填写完毕,提交中...")
  try:
    submit = await page.querySelector('#submit_button')
    await submit.click()
  except AttributeError:
    submit = await page.querySelector('#ctlNext')
    await submit.click()
  if await page.querySelector("#pop_box_msg"):
    print("自动点击智能验证中...")
    await page.evaluate(pageFunction="closeAlert();", force_expr=False)
    await page.evaluate(pageFunction="document.getElementById('rectMask').click();", force_expr=False)

  print("已自动提交!")
  print("提交时间:", time.ctime())


if __name__ == "__main__":
  start = time.time()
  asyncio.get_event_loop().run_until_complete(main())
  end = time.time()
  print("用时:%.2fs" % (end - start))

若有疑问,请在评论区留言。

最后修改:2023 年 10 月 15 日
如果觉得我的文章对你有用,请随意赞赏