前言
最近学校搞调研活动,需要收集问卷,还有份数要求,数量不够,自己来凑,但是手动填写有很麻烦,所以就有了这个项目。
一、自动填写问卷分为几步?
- 首先肯定是要实现自动打开网页,自动点击,这个地方,我搜了以下,基本上都是用的
selenium - 是在我实现了第一步之后,发下这个问卷有反爬,检测到你是脚本运行的,提交不了,所以就要进行反反爬
- 就是实现循环,总不能每一份都手动点击运行对吧
二、具体步骤
1.自动打开网页
这里需要用到chrome浏览器,并且要按照插件,大家参考这个网站 代码如下(示例):
from selenium import webdriver
# 创建浏览器对象
options = webdriver.ChromeOptions()
browser = webdriver.Chrome(options=options)
# 获取待访问的网址
browser.get("https://www.wjx.cn/vm/rlW1bUm.aspx") #根据需要填写url,即问卷链接
这个代码可以自动打开网页,不过没有反反爬,提交问卷的时候就提交不了
代码如下(反反爬):这里不讲反反爬原理,毕竟我也不太懂
from selenium import webdriver
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})
browser.get("https://www.wjx.cn/vm/rlW1bUm.aspx")
这样就实现了网页的打开了
2.通过xpath实现自动点击
代码如下(示例):
browser.find_element_by_xpath('//*[@id="div1"]/div[2]/div[1]/div').click()
#xpath路径:选择要点击的位置,在对应代码出右键,Copy,Copy Xpath
大家先理解这一句代码,是selenium 自带的点击功能,后面的.click() 就表示点击,那么你要告诉他要点击哪里呢?.find_element_by_xpath() 就表示通过xpath来定位,告诉他要点击的地方的xpath,他就知道要点哪里了。
至于怎么找xpath?
在chrome浏览器中右击点检查 用这个工具点击你想要点击的地方 它会自动对应到这个位置对应的代码,对代码右击,选择Copy,选择Copy Xpath,就会自动复制Xpath,把它粘贴到.find_element_by_xpath() 括号内就行了 (而且都是有规律的,你自己找找规律,哪个数字对应题目,哪个数字对应选项)
3.自动填写并提交
代码如下(示例):
from selenium import webdriver
import time #用于休眠
import random #用于生成随机数
import numpy as np
def write(): #定义一个函数用于自动填写、提交问卷
#第一题(单选题)
number = random.randint(1,3) #生成对应选项的随机数,这里有两个选项,随机生成数字1-3
if number == 1: #随机生成的数字为1,则选择选项1
browser.find_element_by_xpath( #xpath路径:选择要点击的位置,再对应代码出右键,Copy,Copy Xpath
'//*[@id="div1"]/div[2]/div[1]/div').click() #利用xpath路径进行寻找,再进行点击.click()操作
elif number == 2: #随机生成的数字为2,则选择选项3
browser.find_element_by_xpath(
'//*[@id="div1"]/div[2]/div[2]/div').click()
elif number == 3: #随机生成的数字为3,则选择选项3
browser.find_element_by_xpath(
'//*[@id="div1"]/div[2]/div[3]/div').click()
#第二题(多选题)
numbers = np.random.randint(4, size=2) #生成对应选项的多个随机数,表示生成[0,5)区间内2个随机整数,可能会有重复
if 1 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[1]/div').click()
if 2 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[2]/div').click()
if 3 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[3]/div').click()
if 4 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[4]/div').click()
#第三题(多选题)
numbers = np.random.randint(4, size=2)
if 4 in numbers: #如果生成的随机数有4,就只选4(概率会大一点)
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[4]/div').click()
elif 4 not in numbers:
if 1 in numbers:
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[1]/div').click()
if 2 in numbers:
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[2]/div').click()
if 3 in numbers:
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[3]/div').click()
time.sleep(1)
#点击提交
browser.find_element_by_xpath(
'//*[@id="ctlNext"]').click()
time.sleep(1)
#点击验证
browser.find_element_by_xpath(
'//*[@id="alert_box"]/div[2]/div[2]/button').click()
time.sleep(1)
browser.find_element_by_xpath(
'// *[ @ id = "rectMask"]').click()
time.sleep(2)
我的每一道题都是自己打的if else 语句,结合生成的随机数字进行选择,好像有人就把他分成2类,单选和多选,然后自动识别题目类型和选项数字,直接调用,我这里用的是最笨的方法。
4.实现循环
代码如下(示例):
i = 0
while i < 50: #(自定义设置问卷数量,可循环刷)
url = "https://www.wjx.cn/vm/rlW1bUm.aspx" #问卷星链接
#打开问卷
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})
browser.get(url)
#调用函数,自动填写问卷并提交
write()
time.sleep(2) #休眠2s
browser.close() #填写完毕关闭页面
i+=1
三、全部代码
代码如下(示例):
from selenium import webdriver #selenium,用于网页控制
import time #用于休眠
import random #用于生成随机数
import numpy as np
def write():
#第一题(单选题)
number = random.randint(1,3) #生成对应选项的随机数,这里有两个选项,随机生成数字1-3
if number == 1: #随机生成的数字为1,则选择选项1
browser.find_element_by_xpath( #xpath路径:选择要点击的位置,再对应代码出右键,Copy,Copy Xpath
'//*[@id="div1"]/div[2]/div[1]/div').click() #利用xpath路径进行寻找,再进行点击.click()操作
elif number == 2: #随机生成的数字为2,则选择选项3
browser.find_element_by_xpath(
'//*[@id="div1"]/div[2]/div[2]/div').click()
elif number == 3: #随机生成的数字为3,则选择选项3
browser.find_element_by_xpath(
'//*[@id="div1"]/div[2]/div[3]/div').click()
#第二题(多选题)
numbers = np.random.randint(4, size=2) #生成对应选项的多个随机数,表示生成[0,5)区间内2个随机整数,可能会有重复
if 1 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[1]/div').click()
if 2 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[2]/div').click()
if 3 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[3]/div').click()
if 4 in numbers:
browser.find_element_by_xpath(
'//*[@id="div2"]/div[2]/div[4]/div').click()
#第三题(多选题)
numbers = np.random.randint(4, size=2)
if 4 in numbers: #如果生成的随机数有4,就只选4(概率会大一点)
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[4]/div').click()
elif 4 not in numbers:
if 1 in numbers:
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[1]/div').click()
if 2 in numbers:
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[2]/div').click()
if 3 in numbers:
browser.find_element_by_xpath(
'//*[@id="div3"]/div[2]/div[3]/div').click()
time.sleep(1)
#提交
browser.find_element_by_xpath(
'//*[@id="ctlNext"]').click()
time.sleep(1)
#验证
browser.find_element_by_xpath(
'//*[@id="alert_box"]/div[2]/div[2]/button').click()
time.sleep(1)
browser.find_element_by_xpath(
'// *[ @ id = "rectMask"]').click()
time.sleep(2)
if __name__=='__main__': #这个没什么作用,就是书写规范,表示运行的主函数
i = 0
while i < 50: #(自定义设置问卷数量,可循环刷)
url = "https://www.wjx.cn/vm/rlW1bUm.aspx" #问卷星链接
#打开问卷
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',
{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})
browser.get(url)
#调用函数,自动填写问卷并提交
write()
time.sleep(2) #休眠2s
browser.close() #填写完毕关闭页面
i+=1
运行视频看这里
总的来说,运行的话可以,不过短时间内份数过多的时候,大概在5、60份时,他的验证方式会变成滑块验证,大家可以休息一段时间再刷,或者学一下怎么通过滑块验证。
|