python自动化------问卷星刷问卷3.0版本

接上,之前做的问卷星刷问卷的功能单一,每个题目只能选一个选项。现在的3.0版本功能增加了计数器(刷了几份问卷)、多选项的选择、通过滑块验证。想要了解之前的相关信息请看下面的链接:

隔壁寝室刷问卷刷疯了,我们寝室则相反,打游戏的同时问卷份数也在增加,隔壁寝室的人投来羡慕的目光,向我要代码!!

python基础知识------生成多个随机数

本篇文章将会将该程序拆分成代码块逐一讲解其功能。

注意:经过本人测试,刷问卷,一次只能刷51份,第52次运行程序时,会出现滑动验证,即使程序中写了过滑动验证的相关代码并且成功通过了滑动滑块,但是问卷星会重新弹出是否进行验证,然后又重新弹出滑动验证码。手动滑动,接下来会进行以上的循环。关闭浏览器,问卷星份数并未增加。

           所以即使增加了滑动验证码的代码,其结果还是只能在短期内刷51份。当然,当出现滑动验证码时,只要暂停程序,过一个小时(具体时间未测量)后又能重新开始刷了。如有不同想法和测试结果,请指正。

目录

一、模块导入

二、代码块的解析

1.生成多选题不重复的随机选项

2.计数器(记录运行次数)

3.伪装selenium

4.滑动验证码---滑动距离

5.滑动验证码---滑动滑块

6.定时运行程序

7.run()函数的编写

三、源代码及结果展示

四、总结


一、模块导入

import random
from selenium import webdriver
import time
from selenium.webdriver import ActionChains
import schedule as schedule

二、代码块的解析

1.生成多选题不重复的随机选项

# 多选题的多个选项
def int_random(m, n, o):
    p = []
    while len(p) < o:
        new_int = random.randint(m, n)
        if (new_int not in p):
            p.append(new_int)
        else:
            pass
    return p

该代码实现的功能是生成m到n之间的o个不重复的数字,可用于多选题随机选项的选择,详细内容请看我之前的博文

python基础知识------生成多个随机数

2.计数器(记录运行次数)

# 计数器
count = 0
def sum():
    global count
    count += 1
    w = print("第{}次运行".format(count))
    return w

这里的global的用法是在局部函数中对全局变量重新赋值,这样就起到了每运行一次程序,计数器计数的功能。

3.伪装selenium

    url = 'https://www.wjx.cn/vm/maBODlH.aspx'
    # 躲避智能检测
    option = webdriver.ChromeOptions()
    option.add_experimental_option('excludeSwitches', ['enable-automation'])
    option.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=option)
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
    })
    driver.get(url)

该代码在之前的博文中讲过具体原因

隔壁寝室刷问卷刷疯了,我们寝室则相反,打游戏的同时问卷份数也在增加,隔壁寝室的人投来羡慕的目光,向我要代码!!

4.滑动验证码---滑动距离

def get_track(distance):  # distance为传入的总距离
    # 移动轨迹
    track = []
    # 当前位移
    current = 0
    # 计算间隔
    t = 0.2
    # 初速度
    v = 0
    while current < distance:
        # 加速度
        a = 50
        v0 = v
        # 当前速度
        v = v0 + a * t
        # 移动距离
        # move = v0 * t + 1 / 2 * a * t * t
        move = v0 * t + a * t
        # 当前位移
        current += move
        # 加入轨迹
        track.append(round(move))
    return track  # track列表 返回的是整个滑动条的多个焦点,可以模拟鼠标的缓慢滑动

首先该代码返回的是track列表(其中包含了移动的轨迹),定义当前位移current=0,时间间隔t=0.2,初始速度v=0,接下来通过判断语句,判断当前距离是否小于你所输入的总距离,如果成立,则通过物理的知识,通过加速度a,速度v计算位移,然后将它加到current中。

注:这里的a、t、v都可以自定义,甚至我连move = v0 * t + 1 / 2 * a * t * t这个公式也更改了。

因为python自动化讲究效率,速度很关键,而且对于这类简单的滑动验证,不用那些先加速后减速的套路,所以只需要一直加速即可。

5.滑动验证码---滑动滑块

def move_to_gap(slider, tracks):  # slider是要移动的滑块,tracks是要传入的移动轨迹
    ActionChains(driver).click_and_hold(slider).perform()
    for x in tracks:
        ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
    time.sleep(0.1)
    ActionChains(driver).release().perform()

 ①ActionChains(driver).click_and_hold(slider).perform()中
      click_and_hold(slider)---点击鼠标左键,不松开,其中slider为需要定位要移动的滑块

        (例如huakuai = driver.find_element_by_css_selector('#nc_1_n1z'))
      perform()---执行该动作;

②接下来遍历tracks

      ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()中

      move_by_offset(xoffset=x, yoffset=0)---鼠标向右移动x的px

③ActionChains(driver).release().perform()中

      release()---释放

    注:4和5一般在一起使用

6.定时运行程序

def run():
    pass

schedule.every(5).seconds.do(run)

while True:
    schedule.run_pending()

run()函数为主函数,通过schedule实现每隔5秒运行一次程序

7.run()函数的编写

代码如下

def run():
    global driver
    url = 'https://www.wjx.cn/vm/maBODlH.aspx'
    # 躲避智能检测
    option = webdriver.ChromeOptions()
    option.add_experimental_option('excludeSwitches', ['enable-automation'])
    option.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=option)
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
    })
    driver.get(url)
    sum()
    # 总共有13个题目
    i = 1
    while i <= 13:
        base_xpath1 = '//*[@id="div{}"]'.format(i)
        base_xpath2 = base_xpath1 + '/div[2]/div'
        a = driver.find_elements_by_xpath(base_xpath2)
        # print(len(a))
        # 在选项个数范围内,随机生成一个数字 如有四个选项,随机生成数字3
        b = random.randint(1, len(a))
        # print(b)
        # 通过随机数字,点击该数字的选项
        # time.sleep(1)
        # 当第六个问题回答第四个选项(其他)时,需要填写
        if i == 6 and b == 4:
            driver.find_element_by_css_selector('#div{} > div.ui-controlgroup > div:nth-child({})'.format(i, b)).click()
            # time.sleep(1)
            # 这里你可以每隔一段时间更改send_keys中的内容,也可以将答案写出来,然后随机选择哪个选项
            driver.find_element_by_css_selector('#tqq6_4').send_keys('QQ群和微信群')
        elif i == 5 or i == 7 or i == 8 or i == 11:
            q = int_random(1, len(a), b)
            # sort函数表示将列表排序,如果未加参数表示从小到大排列
            q.sort()
            for r in q:
                driver.find_element_by_css_selector('#div{} > div.ui-controlgroup > div:nth-child({})'.format(i, r)).click()
                # time.sleep(0.5)
        else:
            driver.find_element_by_css_selector('#div{} > div.ui-controlgroup > div:nth-child({})'.format(i, b)).click()

        # 当第三个问题答案是是时,跳到5
        if i == 3 and b == 1:
            i = 5
        else:
            i += 1
#     # 点击提交按钮
    time.sleep(0.5)
    driver.find_element_by_xpath('//*[@id="ctlNext"]').click()
    # 出现点击验证码验证
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="alert_box"]/div[2]/div[2]/button').click()
    time.sleep(0.5)
    driver.find_element_by_xpath('//*[@id="rectMask"]').click()
    time.sleep(4)
    try:
        huakuai = driver.find_element_by_css_selector('#nc_1_n1z')
        move_to_gap(huakuai, get_track(328))
    except:
        pass
    finally:
        # 关闭页面
        handles = driver.window_handles
        driver.switch_to.window(handles[0])
        time.sleep(0.5)
        # 刷新页面(可要可不要)
        # driver.refresh()
        # 关闭当前页面,如果只有一个页面,则也关闭浏览器
        driver.close()

这里面的代码需要你根据具体问卷星的内容进行改写。

问卷星问卷的网址为浙水院经管学院2020级大学生勤工俭学和兼职问题调查【复制】,大家可以自己查看一下问卷星问卷内容,对于该问卷

首先,题目为13个,所以判断条件为i <= 13,

len(a)为选项的个数,b为在选项个数内随机生成整数

如果第六个问题,随机数b为4时,则还要填写文本内容;

如果是第5、7、8、11个问题,则调用上面1.生成多选题不重复的随机选项的函数,再通过sort()函数将列表从小到大排列(这一过程可省略),最后遍历该列表,选择里面生成的随机选项。

剩下的就是单选题了,这个比较简单

对于那些隐藏的题目,即当且仅当选择了前面某题的某选项才出现时,需要重新在if语句中写,

并且该if语句要放在所以if语句的最后,因为这个if中含有i,如果放前面会因为i提前变化,导致找不到相关内容,最终报错。

写好这些以后,就开始点击提交问卷按钮,并开始进行验证了。刷问卷选项时可以不设间隔时间,但是以下的操作就需要足够时间,需要用到time.sleep(),不然会使得刷问卷失败。所以刷问卷所需时长主要花在验证这里。

    try:
        huakuai = driver.find_element_by_css_selector('#nc_1_n1z')
        move_to_gap(huakuai, get_track(328))
    except:
        pass
    finally:
        # 关闭页面
        handles = driver.window_handles
        driver.switch_to.window(handles[0])
        time.sleep(0.5)
        # 刷新页面(可能不需要)
        # driver.refresh()
        # 关闭当前页面,如果只有一个页面,则也关闭浏览器
        driver.close()

该代码段表示,先执行try代码块,如果发现错误,则执行except代码块,finally表示不管代码会不会报错,都会执行finally代码块。

在本代码中,前51次不会出现滑块验证,因此执行try代码块时本应该会报错,但是我们将except段pass,使得代码不会报错,最终不管代码是否会报错,都会执行finally代码块。

当然,如上所说,即使过了滑动验证,还是会重新弹出滑动验证,导致无法提交,份数也不会增加,所以我们可以不用在代码中加入这段。

    # 点击提交按钮
    time.sleep(0.5)
    driver.find_element_by_xpath('//*[@id="ctlNext"]').click()
    # 出现点击验证码验证
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="alert_box"]/div[2]/div[2]/button').click()
    time.sleep(0.5)
    driver.find_element_by_xpath('//*[@id="rectMask"]').click()
    time.sleep(4)
    # 关闭页面
    handles = driver.window_handles
    driver.switch_to.window(handles[0])
    time.sleep(1)
    # 刷新页面(可能不需要)
    # driver.refresh()
    # 关闭当前页面,如果只有一个页面,则也关闭浏览器
    driver.close()

所以也不需要用到

get_track(distance)和move_to_gap(slider, tracks)这两个函数。

三、源代码及结果展示

# -*- coding: utf-8-*-
import random
from selenium import webdriver
import time
from selenium.webdriver import ActionChains
import schedule as schedule
# 多选题的多个选项
def int_random(m, n, o):
    p = []
    while len(p) < o:
        new_int = random.randint(m, n)
        if (new_int not in p):
            p.append(new_int)
        else:
            pass
    return p
# 计数器
count = 0
def sum():
    global count
    count += 1
    w = print("第{}次运行".format(count))
    return w

def get_track(distance):  # distance为传入的总距离
    # 移动轨迹
    track = []
    # 当前位移
    current = 0
    # 计算间隔
    t = 0.2
    # 初速度
    v = 0
    while current < distance:
        a = 50
        v0 = v
        # 当前速度
        v = v0 + a * t
        # 移动距离
        # move = v0 * t + 1 / 2 * a * t * t
        move = v0 * t + a * t
        # 当前位移
        current += move
        # 加入轨迹
        track.append(round(move))
    return track  # list 返回的是整个滑动条的多个焦点,可以模拟鼠标的缓慢滑动

def move_to_gap(slider, tracks):  # slider是要移动的滑块,tracks是要传入的移动轨迹
    ActionChains(driver).click_and_hold(slider).perform()
    for x in tracks:
        ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
    time.sleep(0.1)
    ActionChains(driver).release().perform()


def run():
    global driver
    url = 'https://www.wjx.cn/vm/maBODlH.aspx'
    # 躲避智能检测
    option = webdriver.ChromeOptions()
    option.add_experimental_option('excludeSwitches', ['enable-automation'])
    option.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=option)
    driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
    })
    driver.get(url)
    sum()
    # 总共有13个题目
    i = 1
    while i <= 13:
        base_xpath1 = '//*[@id="div{}"]'.format(i)
        base_xpath2 = base_xpath1 + '/div[2]/div'
        a = driver.find_elements_by_xpath(base_xpath2)
        # print(len(a))
        # 在选项个数范围内,随机生成一个数字 如有四个选项,随机生成数字3
        b = random.randint(1, len(a))
        # print(b)
        # 通过随机数字,点击该数字的选项
        # time.sleep(1)
        # 当第六个问题回答第四个选项(其他)时,需要填写
        if i == 6 and b == 4:
            driver.find_element_by_css_selector('#div{} > div.ui-controlgroup > div:nth-child({})'.format(i, b)).click()
            # time.sleep(1)
            # 这里你可以每隔一段时间更改send_keys中的内容,也可以将答案写出来,然后随机选择哪个选项
            driver.find_element_by_css_selector('#tqq6_4').send_keys('QQ群和微信群')
        elif i == 5 or i == 7 or i == 8 or i == 11:
            q = int_random(1, len(a), b)
            # sort函数表示将列表排序,如果未加参数表示从小到大排列
            q.sort()
            for r in q:
                driver.find_element_by_css_selector('#div{} > div.ui-controlgroup > div:nth-child({})'.format(i, r)).click()
                # time.sleep(0.5)
        else:
            driver.find_element_by_css_selector('#div{} > div.ui-controlgroup > div:nth-child({})'.format(i, b)).click()

        # 当第三个问题答案是是时,跳到5
        if i == 3 and b == 1:
            i = 5
        else:
            i += 1
#     # 点击提交按钮
    time.sleep(0.5)
    driver.find_element_by_xpath('//*[@id="ctlNext"]').click()
    # 出现点击验证码验证
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="alert_box"]/div[2]/div[2]/button').click()
    time.sleep(0.5)
    driver.find_element_by_xpath('//*[@id="rectMask"]').click()
    time.sleep(4)
    try:
        huakuai = driver.find_element_by_css_selector('#nc_1_n1z')
        move_to_gap(huakuai, get_track(328))
    except:
        pass
    finally:
        # 关闭页面
        handles = driver.window_handles
        driver.switch_to.window(handles[0])
        time.sleep(0.5)
        # 刷新页面(可能不需要)
        # driver.refresh()
        # 关闭当前页面,如果只有一个页面,则也关闭浏览器
        driver.close()

schedule.every(1).seconds.do(run)

while True:
    schedule.run_pending()

该结果刷的是另外一份问卷

四、总结

在发这篇博文之前,我已经帮三个人刷过问卷了,每一种问卷内容都不一样,run()函数需要自己写。

​​​​​​

 其中有些问卷非常复杂(如下),你需要花时间了解问卷,然后再写程序

 

现在,问卷星自动化刷问卷3.0版本已经完结,如果有其他想法的,欢迎和我交流,如果上述有误的,请指正!!

  • 31
    点赞
  • 159
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 53
    评论
### 回答1: Spark 3.0版本中的Spark SQL是一个用于处理结构化数据的模块,它提供了一种基于SQL的接口,可以方便地进行数据查询、过滤、聚合、连接等操作。Spark SQL还支持将结构化数据与非结构化数据(如JSON、Parquet、Avro等)进行无缝集成,同时还提供了一些高级功能,如分区、分桶、窗口函数等。Spark 3.0版本中的Spark SQL还引入了一些新特性,如动态分区、动态分桶、动态过滤等,可以进一步提高数据处理的效率和灵活性。 ### 回答2: Spark 3.0版本中的SparkSQL是一个用于处理结构化数据的分布式查询引擎。它提供了一种基于SQL语言的API,使得开发人员可以使用SQL语句对数据进行查询、转换和分析。 SparkSQL具有以下几个主要特点: 1. 高性能:SparkSQL利用了Spark的弹性分布式计算模型,能够立即处理大规模数据。它通过将查询计划转换为可以在分布式集群上执行的任务来实现高效的查询。 2. 兼容性:SparkSQL兼容Hive,可以直接读取和查询Hive表。它还支持多种文件格式,包括Parquet、ORC、Avro等。 3. 多语言支持:SparkSQL支持多种编程语言,包括Scala、Java、Python和R。这使得开发人员可以使用他们熟悉的语言进行数据查询和分析。 4. 数据源集成:SparkSQL提供了丰富的数据源接口,可以轻松地从各种数据源中读取和写入数据,包括关系型数据库、Hive、HDFS、S3等。 5. 支持流数据处理:SparkSQL不仅可以处理静态的批处理数据,还可以处理实时的流式数据。它提供了结构化流处理(Structured Streaming)功能,可以将流数据视为连续的表,并对其进行查询和转换。 总之,SparkSQL是Spark 3.0版本中的一个重要组件,它提供了一种灵活、高效的方式来处理和分析结构化数据。无论是处理批量数据还是实时流数据,SparkSQL都能在分布式集群上提供高性能的查询和分析能力。 ### 回答3: Spark 3.0版本的Spark SQL是Spark生态系统中的一个重要组件。它提供了用于在Spark上进行结构化数据处理的高级接口。 Spark SQL支持多种数据源,包括Hive、Avro、Parquet、ORC、JSON等,可以方便地读取和写入这些格式的数据。通过Spark SQL,用户可以使用SQL语句来查询、分析和处理数据,同时还能够使用DataFrame和Dataset API进行更灵活和更高级的数据操作。 Spark SQL还提供了一个优化器,能够对SQL查询进行优化,包括谓词下推、投影下推、列剪裁等,以提高查询的性能。此外,Spark SQL还提供了支持多种文件格式的自动schema推断功能,使得用户可以在没有定义表结构的情况下直接读取文件。 在Spark 3.0中,Spark SQL引入了更多的功能和优化。其中包括支持数组和Map类型的数据操作、支持规范化和反规范化数据、支持视图和临时表、支持动态分区写入等。此外,Spark 3.0还引入了Catalyst优化器的新版本,进一步提升了查询性能。 总之,Spark 3.0版本的Spark SQL为用户提供了一个强大而灵活的数据处理工具,在处理大规模结构化数据时具有高性能和易用性的优势。无论是在数据分析、数据仓库建设还是在机器学习和深度学习等领域,Spark SQL都是一款非常有价值的工具。
评论 53
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

knighthood2001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值