麦克表单自动填写提交(pyppeteer完美版)

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

特色:

  1. 用js分析控件,填写更精确,并能处理一定的下拉框,单选框与复选框
  2. 采用pyppeteer,填写速度更快,省去了安装chromedrive的繁琐步骤
  3. 能够进行反爬虫(虽然麦克表单用不上)
注意事项:此程序用python编写,需要配置python及安装相应库(所需库见导入模块处),此版本采用pyppeteer模块,无需chromedriver,极大简化了环境的搭建,注意浏览器安装路径改为你的实际安装路径,个人信息填在字典里。如何安装python库请自行百度(实际直接pip install package name即可),pip换源可参考这篇文章:Linux和Windows的pip换源
# encoding=utf8
# 自动填写麦克表单,适用于全是单项填空的表单和简单下拉框,川农登记信息一般为此格式

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



# 识别二维码函数
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(url):
  # launch方法会新建一个browser对象,然后赋值给browser
  browser = await launch({
    # 谷歌浏览器的安装路径
    'executablePath': 'C:\\Program Files\\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")
  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.querySelectorAll(".fbi_input")
    if not elem:
      await page.goto(url)
      time.sleep(1.5)
    else:
      break
  start = time.time()
  print("开始时间:", time.ctime())
  # 用js对所需填写的表单控件进行精确分析,避免了单选框,复选框,下拉框对程序的干扰。
  temp = await page.evaluate(pageFunction='''() => {
        temp = document.getElementsByClassName("fb_component");
        var names = [];
        for (var j = 0; j < temp.length; j++) {
          i = temp[j].getAttribute("class");
          if (i.indexOf("radio") < 0 && i.indexOf("checkbox") < 0 && i.indexOf("dropDown") < 0)
            names.push(temp[j].getElementsByTagName("span")[0].textContent);
        }
        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 elem[n].type(msg[key])
        n += 1

  # 处理选择框
  choose = '''() => {
        var choice = document.getElementsByTagName("span"); var select = document.getElementsByClassName("mg-dropTrigger");
             // 将结果返回给python程序
             result = [];
             // 先点击下拉选择的框,弹出选项
             for (var i=0; i<select.length; i++)    
               select[i].click();
             for (var i=0; i<choice.length; i++) { 
               if (choice[i].innerHTML == "男") {  
                 choice[i].click();
                 result.push("已选择性别为男");
               }
               if (choice[i].innerHTML == "是") {  
                 choice[i].click();
                 result.push("已选择选项为是");
               }
             } return result;
      }'''
  result = await page.evaluate(pageFunction=choose, force_expr=False)
  # 打印选择框js处理结果
  if result:
    for i in result:
      print(i)
  print("填写完毕,提交中...")
  sub = "document.getElementsByClassName('fb_submitBtn')[0].click()"
  await page.evaluate(sub)
  end = time.time()
  print("已自动提交!")
  print("提交时间:", time.ctime())
  print("用时:%.2fs" % (end - start))

if __name__ == "__main__":
  url = "" # 活动链接
  url = "http://d71ibjcuwhw0zpb2.mikecrm.com/txFEyv2" # 电脑版测试
  # url = "https://www.wjx.top/vm/QGHo4eA.aspx" # 手机版测试
  asyncio.get_event_loop().run_until_complete(main(url))

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

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