问卷星自动填写提交(抢活动专用)
用途:自动抢川农需要填写表单报名的活动,也可根据实际情况修改为其他用途,配合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))
若有疑问,请在评论区留言。