当前位置:   article > 正文

基于selenium实现自动填写问卷星的问卷调查_自动填问卷的工具

自动填问卷的工具

你是否还在为学校天天发的问卷调查而苦恼?

你是否还在为天天填写朋友的问卷调查而苦恼?

你是否还在为没人帮你填写问卷调查而苦恼?

废话不多说,直接上解决方案:

没用用过selenium的小朋友记得先安装配置一下:谷歌浏览器驱动的安装及selenium的安装与使用 - 知乎

 防止有人不看参数说明,再写一遍:

url         为问卷地址参数,

answers     为答案参数
    用列表存放答案,比如如果有3题,第一题多选,第二题单选,第三题多选
    [
        [1, 2], 
        [2], 
        [2, 3]
    ]
    意思就是第一题选A,B     第二题选B      第三题选B,C

select      为模式选择参数,默认为2
    1: 自主模式,根据自己填写的answer进行填写问卷
    2: 随机模式,通过random生成随机数进行填写问卷

flag        为bool类型参数,默认为False
    值为True: 无头模式,即不显示浏览器
    值为False:   正常模式 

注意:由于时间有限,目前我只做了单选和多选这两类选择题的自动填写,后续有时间的话会继续更新其他类型的题;

实现思路都大差不差,大家也可以参考代码自己更新


2023年11月29日 20:51第一次更新

多了如下几种题型:

 type=1

 type=5 

type=6

type=9

2023年12月5日第二次更新 

更新了答案参数用法,由列表改为字典,更加人性化,操作更加简单,可以自己选择题目填写答案。

'''
url         为问卷地址参数,
answers     为答案参数
    用字典存放答案,比如如果有3题,第一题多选,第二题填空,第三题单选
    {
        1: [2, 4],
        2: "无建议",
        3: 3, 
    }
    意思就是第一题选B,D     第二题填无建议      第三题选C

select      为模式选择参数,默认为2
    1: 自主模式,根据自己填写的answer进行填写问卷
    2: 随机模式,通过random生成随机数进行填写问卷

flag        为bool类型参数,默认为False
    值为True: 无头模式,即不显示浏览器
    值为False:   正常模式 
'''

当填写问卷提交过快时,会有反爬,这次更新解决了三种反爬:

  1. 对话框确认验证
  2. 智能检测按钮验证
  3. 滑块验证

可以根据输入指定填写次数

 下面直接上代码:

  1. import random
  2. import time
  3. from selenium import webdriver
  4. from selenium.webdriver.common.by import By
  5. from selenium.webdriver import ChromeOptions, ActionChains
  6. '''
  7. url 为问卷地址参数,
  8. answers 为答案参数
  9. 用字典存放答案,比如如果有3题,第一题多选,第二题填空,第三题单选
  10. {
  11. 1: [2, 4],
  12. 2: "无建议",
  13. 3: 3,
  14. }
  15. 意思就是第一题选B,D 第二题填无建议 第三题选C
  16. select 为模式选择参数,默认为2
  17. 1: 自主模式,根据自己填写的answer进行填写问卷
  18. 2: 随机模式,通过random生成随机数进行填写问卷
  19. flag 为bool类型参数,默认为False
  20. 值为True: 无头模式,即不显示浏览器
  21. 值为False: 正常模式
  22. '''
  23. class WenJuanXing:
  24. def __init__(self, url, answers, select=2, flag=False):
  25. # 初始化变量
  26. self.driver = None
  27. self.url = url
  28. self.answers = answers
  29. self.select = select
  30. # 初始化浏览器驱动
  31. self.options = ChromeOptions()
  32. self.options.headless = flag
  33. self.options.add_experimental_option('excludeSwitches', ['enable-automation'])
  34. self.options.add_experimental_option('useAutomationExtension', False)
  35. def parse(self):
  36. divs = self.driver.find_elements(By.CSS_SELECTOR, '.field.ui-field-contain') # 拿到所有的问题
  37. for div in divs:
  38. div_num = divs.index(div) + 1 # 题号
  39. div_type = int(div.get_attribute('type')) # 问题类型
  40. if div_type == 1: # 填空题
  41. question = div.find_element(By.CSS_SELECTOR, 'input')
  42. if self.select == 1:
  43. question.send_keys(self.answers[div_num])
  44. else:
  45. input_type = question.get_attribute('type')
  46. if input_type == "text":
  47. question.send_keys("无建议")
  48. elif input_type == "tel":
  49. question.send_keys("18")
  50. if div_type == 3: # 单选题
  51. checks = div.find_elements(By.CSS_SELECTOR, '.ui-radio') # 拿到所有的选项
  52. if self.select == 1: # 模式1:自主模式
  53. checks[self.answers[div_num] - 1].click()
  54. else: # 模式2:随机模式
  55. check_num = len(checks) # 选项数目
  56. ans = random.randint(1, check_num) # 随机生成答案
  57. checks[ans - 1].click()
  58. if div_type == 4: # 多选题
  59. checks = div.find_elements(By.CSS_SELECTOR, '.ui-checkbox') # 拿到所有选项
  60. if self.select == 1: # 模式1:自主模式
  61. for ans in self.answers[div_num]:
  62. checks[ans - 1].click()
  63. else: # 模式2:随机模式
  64. check_num = len(checks) # 选项数目
  65. num = random.randint(1, check_num) # 随机生成选项数
  66. ansArr = [] # 随机生成的答案数组
  67. for i in range(num):
  68. c = random.randint(1, check_num) # 随机生成答案
  69. if c not in ansArr:
  70. ansArr.append(c)
  71. for ans in ansArr: # 根据随机数组里的答案进行选择
  72. checks[ans - 1].click()
  73. if div_type == 5:
  74. lis = div.find_elements(By.CSS_SELECTOR, '.onscore>li')
  75. if self.select == 1:
  76. lis[answers[div_num] - 1].click()
  77. else:
  78. lis_num = len(lis)
  79. ans = random.randint(1, lis_num)
  80. lis[ans - 1].click()
  81. if div_type == 6:
  82. trs = div.find_elements(By.CSS_SELECTOR, 'tr[tp="d"]')
  83. for tr in trs:
  84. tds = tr.find_elements(By.CSS_SELECTOR, 'td>a')
  85. if self.select == 1:
  86. tr_index = trs.index(tr)
  87. tds[self.answers[div_num][tr_index] - 1].click()
  88. else:
  89. td_num = len(tds)
  90. ans = random.randint(1, td_num) # 随机生成答案
  91. tds[ans - 1].click()
  92. if div_type == 9:
  93. questions = div.find_elements(By.CSS_SELECTOR, 'input')
  94. for question in questions:
  95. if self.select == 1:
  96. que_index = questions.index(question)
  97. question.send_keys(self.answers[div_num][que_index])
  98. else:
  99. input_type = question.get_attribute('type')
  100. inputmode = question.get_attribute('inputmode')
  101. if input_type == "text":
  102. if inputmode == "decimal":
  103. min_num = int(question.get_attribute('min'))
  104. max_num = int(question.get_attribute('max'))
  105. ans = random.randint(min_num, max_num)
  106. question.send_keys(ans)
  107. print(f'第{div_num}题已做完')
  108. self.driver.find_element(By.CSS_SELECTOR, '#ctlNext').click() # 提交
  109. # 验证
  110. self.verify()
  111. print('提交成功')
  112. def verify(self):
  113. try:
  114. self.driver.find_element(By.CSS_SELECTOR, '#layui-layer1 .layui-layer-btn0').click()
  115. time.sleep(1)
  116. print('点击对话框确认验证')
  117. except:
  118. print('没有对话框验证')
  119. try:
  120. self.driver.find_element(By.CSS_SELECTOR, '#rectMask').click()
  121. time.sleep(3)
  122. print('有智能检测按钮验证')
  123. except:
  124. print('没有智能检测按钮验证')
  125. # 滑块验证
  126. try:
  127. slider = self.driver.find_element(By.XPATH, '//*[@id="nc_1__scale_text"]/span')
  128. if str(slider.text).startswith("请按住滑块"):
  129. width = slider.size.get('width')
  130. ActionChains(self.driver).drag_and_drop_by_offset(slider, width, 0).perform()
  131. print('滑块验证')
  132. except:
  133. print('没有滑块验证')
  134. def run(self):
  135. # 启动浏览器跳转到答题页面
  136. self.driver = webdriver.Chrome(options=self.options)
  137. self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
  138. "source": """
  139. Object.defineProperty(navigator, 'webdriver', {
  140. get: () => undefined
  141. })
  142. """
  143. })
  144. self.driver.get(self.url)
  145. self.driver.implicitly_wait(5)
  146. self.driver.maximize_window() # 最大化浏览器窗口
  147. # 做题
  148. self.parse()
  149. # 阻塞和关闭
  150. # time.sleep(1)
  151. # input()
  152. self.driver.close()
  153. if __name__ == '__main__':
  154. url = '问卷url'
  155. answers = {
  156. 1: [2, 4], # 1
  157. 2: [2, 5], # 2
  158. 3: 3, # 3·
  159. 4: [1, 3, 5], # 4
  160. 5: [1, 2, 4], # 5
  161. 6: 2, # 6·
  162. 7: 3, # 7·
  163. 8: [4, 5], # 8
  164. 9: 1, # 9·
  165. 10: 2, # 10·
  166. 11: [2, 4, 5], # 11
  167. 12: [1, 3, 4], # 12
  168. 13: [1, 4, 5], # 13
  169. 14: [1, 2, 5], # 14
  170. 15: 1 # 15·
  171. }
  172. select = 2
  173. flag = False
  174. wenjuan = WenJuanXing(url, answers, select=select, flag=False)
  175. # wenjuan.run()
  176. num = int(input('请输入你要提交的次数'))
  177. for i in range(num):
  178. print(f'===============第{i+1}次==================')
  179. wenjuan.run()

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/444317
推荐阅读
相关标签
  

闽ICP备14008679号