Python自动化问卷填写-问卷星(含完整代码)

目录

  • 一、环境安装
  • 二、代码分析
    • (一)库的引用
    • (二)驱动的运行
    • (三)各类题型的程序
    • (四)主程序(根据问卷客制)
  • 三、完整代码

由于网上的问卷星填写代码良莠不齐,搜索半天也没有一个可以正常运行,故发奋图强,手撕Python,脚踏问卷星,从此问卷不愁!!!

请遵纪守法,勿用于任何不正当位置!!!

本文已修改,解决了运行过程中或报错的问题!

一、环境安装

Python自动化问卷填写-问卷星(含完整代码)_第1张图片
本次实战需要用到numpyrandomtimeselenium库,关于库的安装,大家可以自行百度,如有需要可以反馈告知,博主尽量出一期有关库的安装与简单使用实战分析!

重点!!! 大家自行在 chrome://settings/help 查看自己电脑上安装的的chrome版本
Python自动化问卷填写-问卷星(含完整代码)_第2张图片
并在https://registry.npmmirror.com/binary.html?path=chromedriver/网站下载对应版本的chromedriver,如果不是对应版本,程序会报错!!!

二、代码分析

(一)库的引用

import numpy
import random
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options

(二)驱动的运行

def Chrome(url):
    # 实例化一个启动参数对象
    chrome_options = Options()
    # 添加启动参数
    chrome_options.add_argument(
        'user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
        'Chrome/79.0.3945.130 Safari/537.36"')  # 添加请求头
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')

    # 防止被识别
    chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 设置开发者模式启动

    chrome_options.add_experimental_option('useAutomationExtension', False)  # 关闭selenium对chrome driver的自动控制

    # chrome_options.minimize_window()  # 网页最大化,已经无法使用
    # chrome_options.add_argument('--start-maximized')  # 最大化运行(全屏窗口),不设置,取元素会报错
    chrome_options.add_argument('headless')  # 设置浏览器以无界面方式运行
    browser = webdriver.Chrome(options=chrome_options)  # 设置驱动程序,启动浏览器  (实现以特定参数启动)
    browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
                            {
                                'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})  # 用来执行Chrome开发这个工具命令
    browser.get(url)  # 获取问卷信息(此处填问卷链接)
    return browser

(三)各类题型的程序

  1. 单选题
def One_choice(num, sum, *args):
    # sum是总共有多少选项 num是题号
    if len(args) != 0:
        js = "document.getElementById(\"q" + str(num) + "_" + str(args[0]) + "\" ).checked = true"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
        js = "document.getElementById(\"q" + str(num) + "_" + str(args[0]) + "\").click()"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
    else:
        randomId = random.randint(1, sum)  # 随机点击第一个选项或第二个选项
        # js实现方式
        js = "document.getElementById(\"q" + str(num) + "_" + str(randomId) + "\" ).checked = true"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
        js = "document.getElementById(\"q" + str(num) + "_" + str(randomId) + "\").click()"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
    time.sleep(0.2)  # 延时 太快会被检测是脚本
  1. 多选题
def Multiple_choices(num, sum, *args):
    # num是总共有多少选项
    type = bool(len(args))
    match type:
        case 1:
            for i in args:
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\" ).checked = true"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\").click()"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                time.sleep(0.1)
        case 0:
            randomAll = numpy.random.choice([i for i in range(1, sum)],
                                            random.randint(int(sum / 2), sum + 1))  # 随机生成几个选项
            for i in randomAll:
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\" ).checked = true"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\").click()"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                time.sleep(0.1)

    time.sleep(0.2)  #
  1. 滑动函数
def slide(driver, distance):  # 用于屏幕滚动
    # 测算出最大的距离根据电脑屏幕分辨率而异,一般填写400到800,800是最大滑动距离
    js = "var q=document.documentElement.scrollTop=" + str(distance)
    driver.execute_script(js)
    time.sleep(0.2)
  1. 提交函数
def Submit(browser):
    # 点击提交
    submit = browser.find_element(By.XPATH, "//*[@id='ctlNext']")  # 网页源代码的xpath
    submit.click()  # 点击
    # 延时 太快会被检测是脚本
    time.sleep(0.1)
  1. 验证函数
def Verify():
    # 点击提交
    try:
        aasure = browser.find_element(By.XPATH, "//*[@id='layui-layer1']/div[3]/a")
    except:
        aasure = browser.find_element(By.XPATH, "//*[@class='layui-layer-btn0']")
        print("Error")
        time.sleep(600)

    asure = aasure  # 网页源代码的xpath
    asure.click()  # 点击
    time.sleep(1)
    verify = browser.find_element(By.XPATH, "//*[@id='SM_BTN_1']")  # 网页源代码的xpath
    verify.click()  # 点击
    # 延时 太快会被检测是脚本S
    time.sleep(5)

(四)主程序(根据问卷客制)

if __name__ == '__main__':
    url = 'https://www.wjx.cn/vm/xxxxxxxx.aspx'
    # 你的问卷链接
    t1=time.time()
    for i in range(80):
        browser = Chrome(url)
        One_choice(1, 5)
        slide(browser, 630)
        One_choice(2, 2)
        One_choice(3, 4, 3)
        slide(browser, 1230)
        Multiple_choices(4, 6)
        slide(browser, 1830)
        Multiple_choices(5, 7)
        One_choice(6, 3)
        Multiple_choices(7, 5)
        slide(browser, 2230)
        One_choice(8, 2)
        Multiple_choices(9, 6)
        slide(browser, 2830)
        Multiple_choices(10, 5)
        slide(browser, 3230)
        Multiple_choices(11, 5)
        slide(browser, 3630)

        Submit(browser)
        Verify()
        browser.close()
        min=int((time.time()-t1)//60)
        sec = round((time.time() - t1) % 60, 2)
        print(i, f"已经完成!!!  耗时{min}min   {sec}sec")

切记切记 browser.quit()不能少 每一次运行结束,都要结束一次网页,否则不能连续填写

三、完整代码

如果效果不错的话,将来开发一个更加自动化的版本,实现题目自动识别。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :问卷星.py
# @Time      :2023/4/26 13:26
# @Author    :YKW
import numpy
import random
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options


def Chrome(url):
    # 实例化一个启动参数对象
    chrome_options = Options()
    # 添加启动参数
    chrome_options.add_argument(
        'user-agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
        'Chrome/79.0.3945.130 Safari/537.36"')  # 添加请求头
    chrome_options.add_argument('--disable-blink-features=AutomationControlled')

    # 防止被识别
    chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])  # 设置开发者模式启动

    chrome_options.add_experimental_option('useAutomationExtension', False)  # 关闭selenium对chrome driver的自动控制

    # chrome_options.minimize_window()  # 网页最大化,已经无法使用
    # chrome_options.add_argument('--start-maximized')  # 最大化运行(全屏窗口),不设置,取元素会报错
    chrome_options.add_argument('headless')  # 设置浏览器以无界面方式运行
    browser = webdriver.Chrome(options=chrome_options)  # 设置驱动程序,启动浏览器  (实现以特定参数启动)
    browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
                            {
                                'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})  # 用来执行Chrome开发这个工具命令
    browser.get(url)  # 获取问卷信息(此处填问卷链接)
    return browser


def One_choice(num, sum, *args):
    # sum是总共有多少选项 num是题号
    if len(args) != 0:
        js = "document.getElementById(\"q" + str(num) + "_" + str(args[0]) + "\" ).checked = true"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
        js = "document.getElementById(\"q" + str(num) + "_" + str(args[0]) + "\").click()"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
    else:
        randomId = random.randint(1, sum)  # 随机点击第一个选项或第二个选项
        # js实现方式
        js = "document.getElementById(\"q" + str(num) + "_" + str(randomId) + "\" ).checked = true"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
        js = "document.getElementById(\"q" + str(num) + "_" + str(randomId) + "\").click()"
        browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
    time.sleep(0.2)  # 延时 太快会被检测是脚本


def Multiple_choices(num, sum, *args):
    # num是总共有多少选项
    type = bool(len(args))
    match type:
        case 1:
            for i in args:
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\" ).checked = true"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\").click()"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                time.sleep(0.1)
        case 0:
            randomAll = numpy.random.choice([i for i in range(1, sum)],
                                            random.randint(int(sum / 2), sum + 1))  # 随机生成几个选项
            for i in randomAll:
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\" ).checked = true"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                js = "document.getElementById(\"q" + str(num) + "_" + str(i) + "\").click()"
                browser.execute_script(js)  # 使用js实现点击的效果(调用js方法,同时执行javascript脚本)
                time.sleep(0.1)

    time.sleep(0.2)  #


def Blank():
    pass


def slide(driver, distance):  # 用于屏幕滚动
    # 测算出最大的距离根据电脑屏幕分辨率而异,一般填写400到800,800是最大滑动距离
    js = "var q=document.documentElement.scrollTop=" + str(distance)
    driver.execute_script(js)
    time.sleep(0.2)


def Submit(browser):
    # 点击提交
    submit = browser.find_element(By.XPATH, "//*[@id='ctlNext']")  # 网页源代码的xpath
    submit.click()  # 点击
    # 延时 太快会被检测是脚本
    time.sleep(0.1)


def Verify():
    # 点击提交
    try:
        aasure = browser.find_element(By.XPATH, "//*[@id='layui-layer1']/div[3]/a")
    except:
        aasure = browser.find_element(By.XPATH, "//*[@class='layui-layer-btn0']")
        print("Error")
        time.sleep(600)

    asure = aasure  # 网页源代码的xpath
    asure.click()  # 点击
    time.sleep(1)
    verify = browser.find_element(By.XPATH, "//*[@id='SM_BTN_1']")  # 网页源代码的xpath
    verify.click()  # 点击
    # 延时 太快会被检测是脚本S
    time.sleep(5)


if __name__ == '__main__':
    url = 'https://www.wjx.cn/vm/OHoyYV3.aspx'
    t1=time.time()
    for i in range(80):
        browser = Chrome(url)
        One_choice(1, 5)
        slide(browser, 630)
        One_choice(2, 2)
        One_choice(3, 4, 3)
        slide(browser, 1230)
        Multiple_choices(4, 6)
        slide(browser, 1830)
        Multiple_choices(5, 7)
        One_choice(6, 3)
        Multiple_choices(7, 5)
        slide(browser, 2230)
        One_choice(8, 2)
        Multiple_choices(9, 6)
        slide(browser, 2830)
        Multiple_choices(10, 5)
        slide(browser, 3230)
        Multiple_choices(11, 5)
        slide(browser, 3630)

        Submit(browser)
        Verify()
        browser.close()
        min=int((time.time()-t1)//60)
        sec = round((time.time() - t1) % 60, 2)
        print(i, f"已经完成!!!  耗时{min}min   {sec}sec")
        # browser.quit()


好用的话,别忘了点赞收藏呦!!!

你可能感兴趣的:(爬虫实战,python基础,python,自动化,chrome,学习,动态规划)