萌生想法的原因
学校的一些学分要自己抢公众号的活动修满的,要蹲点等公众号发的定时问卷开始填写,几乎秒没。
每次和舍友一起抢,发现大家手速网速各有不同,最后几家欢喜几家愁。
于是萌生了想法——通过代码解决这个问卷星抢活动,定时定点按照相关内容填写,然后自动提交。
目前只在学校学过一点简单的python,经过查阅了一番资料终于弄出了一个符合我目前设想的效果。
第一代代码
在微信公众号找到了一段代码,修改了一些参数打算就开始run了。
1.参考的代码
2.代码展示
import time
from selenium import webdriver
#启动谷歌浏览器
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(2)
driver.get("问卷网址") # 输入网址
def dingshikQ(time, driver, name, nianji, number, Email):
time_start = time.time() #开始计时
print(time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime()))
driver.refresh()
#设置显式等待
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium import webdriver
wait1 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait1.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]")))
# 开始填写
driver.find_element_by_xpath("//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]").send_keys("%s"%name) #输入姓名
driver.find_element_by_xpath("//div[contains(text(),'年级')]/following-sibling::div[1]/input[1]").send_keys("%s"%nianji) #输入年级
driver.find_element_by_xpath("//div[contains(text(),'学号')]/following-sibling::div[1]/input[1]").send_keys("%s"%number) #输入学号
driver.find_element_by_xpath("//div[contains(text(),'邮箱')]/following-sibling::div[1]/input[1]").send_keys("%s"%Email) #输入邮箱
# 点击提交
driver.find_element_by_xpath("//div[contains(text(),'提交')]").click()
if '请点击'in driver.find_element_by_xpath("//div[contains(text(),'请点击')]").text:
driver.refresh() # #浏览器刷新(点击刷新按钮)
wait2 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait2.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'是否继续')]")))
driver.find_element_by_xpath("//button[contains(text(),'确认')]").click()
wait3 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait3.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'提交')]"))) #这里必须是三个括号
driver.find_element_by_xpath("//div[contains(text(),'提交')]").click()
time_end = time.time() #结束计时
time_c= time_end - time_start #运行所花时间
print('time cost=%.1fs'%time_c)
name='姓名'
nianji='年级'
number='12345678'
Email='12345678@163.com'
dingshikQ(time, driver, name, nianji, number, Email)
3.发现的问题及解决方案
修改了一些参数run了以后,发现run不起来。经过一番资料查阅,发现是selenium库的更新换代,引用一些模块的时候方式变化了。
然后就增加了‘from selenium.webdriver.support.wait import WebDriverWait‘的引用和修改了每一条xpath的引用,代码终于run起来了
引入WebDriverWait模块参考的博客
xpath路径引用方式的修改参考博客
第二代代码
1.代码展示和效果图
import time
from selenium import webdriver
#启动火狐浏览器
driver = webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(2)
driver.get("问卷地址") # 输入网址
def dingshikQ(time, driver, name, nianji, number, Email):
time_start = time.time() #开始计时
print(time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime()))#输出本地时间
driver.refresh() #刷新浏览器
#设置显式等待
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
wait1 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait1.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]")))
# 开始填写
driver.find_element(By.XPATH,"//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]").send_keys("%s"%name) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'年级')]/following-sibling::div[1]/input[1]").send_keys("%s"%nianji) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'学号')]/following-sibling::div[1]/input[1]").send_keys("%s"%number) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'邮箱')]/following-sibling::div[1]/input[1]").send_keys("%s"%Email) #输入
# 点击提交
driver.find_element(By.XPATH,"//div[contains(text(),'提交')]").click()
if '请点击'in driver.find_element(By.XPATH,"//div[contains(text(),'请点击')]").text:
driver.refresh() # #浏览器刷新(点击刷新按钮)
wait2 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait2.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'是否继续')]")))
driver.find_element(By.XPATH,"//button[contains(text(),'确认')]").click()
wait3 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait3.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'提交')]"))) #这里必须是三个括号
driver.find_element(By.XPATH,"//div[contains(text(),'提交')]").click()
time_end = time.time() #结束计时
time_c= time_end - time_start #运行所花时间
print('time cost=%.1fs'%time_c)
name='姓名'
nianji='年级'
number='12345678'
Email='12345678@163.com'
dingshikQ(time, driver, name, nianji, number, Email)
2.发现的问题
run了以后电脑自动打开并填写了,但会遇到一个智能验证的按钮,电脑操作太快没反应过就到了上述画面。即使我点了如图的确定再重新手打后,按智能验证的按钮还是不能通过。
3.解决方案:
上csdn搜索相关解决问卷星的智能验证按钮的问题。发现原来这是问卷星的发爬虫的一种机制,通过识别selenium就会弹出这个按钮。目前最新能够解决的办法是:
①下载旧版chrome浏览器
要用chrome浏览器打开问卷地址,而且是还要下载旧版的chrome浏览器复制旧版的chrome.exe到python的工作目录。
参考博客
下载旧版chrome并复制到python工作目录参考博客
②引入一段反反爬虫的代码
代码具体如下:
url = "问卷地址" #实例url
option = webdriver.ChromeOptions()
option.add_experimental_option('excludeSwitches', ['enable-automation'])
option.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(service=s,options=option)
driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'
})
driver.get(url)
参考博客
引入反反爬虫参考代码
③模拟点击智能验证按钮的代码:
代码具体如下
# 先点确认
try:
browser.find_element(By.XPATH, '//*[@id="layui-layer1"]/div[3]/a[1]').click()
time.sleep(1)
except:
pass
# 再点智能验证提示框,进行智能验证
try:
browser.find_element(By.XPATH, '//*[@id="SM_BTN_WRAPPER_1"]').click()
time.sleep(3)
except:
pass
————————————————
版权声明:本文为CSDN博主「理工大猪猪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:
参考博客
点击智能验证按钮的代码参考博客
修改后的第三代代码
1.代码展示
按照上述操作修改了自己的代码如下:
import time
from selenium import webdriver
#反反爬虫
from selenium.webdriver.chrome.options import Options
url = "问卷地址" #实例url
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)
#定义抢课函数
def dingshikQ(time, driver, name, nianji, number, Email):
time_start = time.time() #开始计时
print(time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime()))#输出本地时间
driver.refresh() #刷新浏览器
#设置显式等待
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
wait1 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait1.until(EC.presence_of_element_located((By.XPATH,"//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]")))
# 开始填写
driver.find_element(By.XPATH,"//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]").send_keys("%s"%name) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'学号')]/following-sibling::div[1]/input[1]").send_keys("%s"%nianji) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'学院')]/following-sibling::div[1]/input[1]").send_keys("%s"%number) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'请输入您的手机号码')]/following-sibling::div[1]/input[1]").send_keys("%s"%Email) #输入
# 点击提交
driver.find_element(By.XPATH,"//div[contains(text(),'提交')]").click()
# 先点确认
try:
driver.find_element(By.XPATH, '//*[@id="layui-layer1"]/div[3]/a[1]').click()
time.sleep(1)
except:
pass
# 再点智能验证提示框,进行智能验证
try:
driver.find_element(By.XPATH, '//*[@id="SM_BTN_WRAPPER_1"]').click()
time.sleep(3)
except:
pass
time_end = time.time() #结束计时
time_c= time_end - time_start #运行所花时间
print('time cost=%.1fs'%time_c)
name='林芝'
nianji='大一'
number='12345678'
Email=159123456789
dingshikQ(time, driver, name, nianji, number, Email)
2.效果图
3.发现的问题以及解决方案:
还是没能自动点击这个按钮。后来仔细对比自己的代码和原文博客的代码,原来是那段反反爬虫的代码要放在定义的函数下面。
对比参考的博客
然后就run了,在问卷星发布的问卷后台那里一看,果然看到了自己刚交的问卷。
第四代代码(终版)
代码展示
还添加了定时的效果(还有一些小改动,删除了函数的形参driver、显示等待、计时功能,添加了print('恭喜!问卷提交成功!'))
#引入一些需要用到的库
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
#定义抢活动函数
def dingshikQ(time, name, nianji, number, Email):
while True:
time_now=time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime())
#定时问卷
if time_now=="2023-02-08-19:28:00":
#解决反爬虫的参数
url = "https://www.wjx.cn/vm/P3JxRus.aspx" #实例url
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)
# 开始填写
driver.find_element(By.XPATH,"//div[contains(text(),'学院名称')]/following-sibling::div[1]/input[1]").send_keys("%s"%name) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'学号')]/following-sibling::div[1]/input[1]").send_keys("%s"%nianji) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'姓名')]/following-sibling::div[1]/input[1]").send_keys("%s"%number) #输入
driver.find_element(By.XPATH,"//div[contains(text(),'专业')]/following-sibling::div[1]/input[1]").send_keys("%s"%Email) #输入
submit = driver.find_element(By.XPATH,"//*[@id='ctlNext']") #网页源代码的xpath
submit.click() #点击
#延时 太快会被检测是脚本
time.sleep(0.5)
# 模拟点击智能验证按钮
# 先点确认
wait3 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait3.until(EC.presence_of_element_located((By.XPATH,'//*[@id="layui-layer1"]/div[3]/a[1]')))
driver.find_element(By.XPATH,'//*[@id="layui-layer1"]/div[3]/a[1]').click()
time.sleep(1)
# 再点智能验证提示框,进行智能验证
wait3 = webdriver.support.wait.WebDriverWait(driver,60,0.01)
wait3.until(EC.presence_of_element_located((By.XPATH,'//*[@id="SM_BTN_WRAPPER_1"]')))
driver.find_element(By.XPATH,'//*[@id="SM_BTN_WRAPPER_1"]').click()
time.sleep(3)
print('恭喜!问卷提交成功!')
name='经济与管理'
nianji='20975356'
number='小欧欧'
Email='工商管理'
dingshikQ(time, name, nianji, number, Email)
觉得还可以改善的地方:
①运行的时间问题
因为防止被检测出是脚本添加了sleep(),增加了运行时间;但是增加了运行时间同时降低提交问卷的速度,不利于和学校那些’手速怪‘竞争名额。(试过不用sleep,但是太短的时间后台收不到问卷)
②其他可能出现的情形
问卷还有微信登录和文本检测的功能,如何解决微信登录还有手机号码的输入时而文本时而数字的问题。
③做成一个插件
做成一个插件,一打开就有一个窗口填写相关的数值,不需要一直翻找代码那么麻烦