问卷星脚本

date
Oct 28, 2022
slug
wenjuanxing
status
Published
tags
技术
summary
用pyppeteer实现的问卷星脚本,可以绕过问卷星的脚本检测
type
Post
学校通过问卷星来限定学术会议的报名,故实现一个脚本来减少不必要的情绪波动
友情提示:
赵sx,我就知道你点开了!你现在关闭该教程还来得及,若继续阅读,即是同意请dino一个月的黄焖鸡😘

代码:

好像不好直接下载,那还是贴在文末吧

使用方法:

1、装依赖
这没啥说的
2、修改
修改姓名、学号
修改chrome安装路径,并将用户文件useless前路径改为你存放代码处的路径

在每步操作时,都设置了await asyncio.sleep(0.5)来模拟真实操作
sleep时间可以自行设置,低于某个阈值时会触发问卷星的智能检测
3、win用户创建本地执行
此电脑右键进入管理
notion image
点击任务计划程序库后创建任务
新建触发器,建议新建三个,这样短时间的多次会议报名就不会太麻烦
notion image
新建操作,程序是python路径,添加参数是代码路径,起始于是代码所在文件夹路径
notion image
 
存在问题:
单选和下拉框默认选第一个,这不影响报名就不整了
仅支持单次单人使用,第二个人开始似乎不好跳转url
当然了
遇事不决just do a try

脚本不影响手动操作,请在报名时稍加监督和必要时的操作
(需求和反馈可直接在评论区提出
 
代码:
# code by dino
# less is more

import asyncio
from pyppeteer import launch
from pyppeteer_stealth import stealth    # 反爬虫第三方库


url = 'https://www.wjx.cn/vm/h4wojWx.aspx#'  # test

# url = 'https://www.wjx.cn/vm/Qh4xNft.aspx'
# url = 'https://www.wjx.cn/vm/PU1UtV0.aspx'
# url = 'https://www.wjx.cn/vm/Q0ln6Nf.aspx?pwx=1'
name = "小恐龙先生"
grade = "2022级"
card = "100105110111"

async def main(url, name, grade, card):
    # launch方法会新建一个browser对象,然后赋值给browser
    browser = await launch({
        # 路径就是你的谷歌浏览器的安装路径
        'executablePath': 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
        # Pyppeteer 默认使用的是无头浏览器,所以要显示需要给False
        'headless': False,
        # 设置Windows-size和Viewport大小来实现网页完整显示
        'args': ['--no-sandbox', '--window-size=1366,850'],
        # 移除Chrome正受到自动测试软件的控制
        'ignoreDefaultArgs': ['--enable-automation'],
        # 用户文件
        'userDataDir': 'D:\\Code\\wenjuanxing\\useless'
    })

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

    # 调用了Page对象的goto方法就相当于在浏览器中输入问卷的网址,浏览器跳转到了对应的页面进行加载
    await page.goto(url)
    await page.evaluate('window.scrollBy(0, document.body.scrollHeight)')


    answers = await page.querySelectorAll(".ui-field-contain")
    i = 0
    for answer in answers:
        await asyncio.sleep(0.5)
        try:
            i += 1
            title = await page.evaluate('(element) => element.textContent',answer)
            title_lst = title.split('*')
            if len(title_lst[-1]) <= 1:
                if ("姓名" in title or "名字" in title):
                    idfind="#q%d"%i
                    await page.type(idfind, name)
                elif "年级" in title:
                    idfind="#q%d"%i
                    await page.type(idfind, grade)
                elif "学号" in title:
                    idfind="#q%d"%i
                    await page.type(idfind, card)
                elif "性别" in title:
                    idfind="#q%d"%i
                    await page.type(idfind, '男')
            elif '请选择' in title_lst[-1]:
                # 下拉框默认选第一个
                idfind="select[id='q%d']"% i
                await page.select(idfind,'1')
            else:
                # 单选题默认选第一个
                selector = "#div%d > div.ui-controlgroup.column1 > div:nth-child(1) > span > a" % i
                confirm = await page.querySelector(selector)
                await confirm.click()
        except:
            continue 

    # 删除弹窗提示:继续作答
    confirm = await page.querySelector("#layui-layer1 > span.layui-layer-setwin > a")
    if confirm != None:
        await asyncio.sleep(0.5)
        await confirm.click()

    # 找到提交按钮提交
    await asyncio.sleep(0.5)
    submit = await page.querySelector('#ctlNext')
    await submit.click()
    await asyncio.sleep(0.5)

    confirm = await page.querySelector(".layui-layer-btn0")
    if confirm != None:
        await confirm.click()
        submit = await page.querySelector('#captcha')
        await asyncio.sleep(0.5)
        await submit.click()

    # print(end-start)
    await asyncio.sleep(30)                 # 页面延迟30s看是否提交成功,或出错
    await browser.close()

asyncio.get_event_loop().run_until_complete(main(url, name, grade, card))

© Dino 2021 - 2023