雨课堂自动签到py脚本
- 准备工作
- 指定学习通网址并打开页面进行手动登录
- 通过检测元素找到课程链接
- 判断上课状态
- 找到科目元素
- 验证上课状态的刷新bug
- 重复操作第一个课程
- 完整代码
准备工作
开发环境:PyCharm
准备库:selenium、time
首先导入库并创建实例(相应库可以使用pip安装或直接在PyCharm的左下角软件包选项中下载,我的主页资源附带了我用到的EdgeDriver)
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
edge_options = Options()
edge_options.add_experimental_option("detach",True)
# 设置EdgeDriver路径
webdriver_service = Service('E:\\box\\pachong\\msedgedriver.exe') # 替换为您的EdgeDriver路径
# 创建Edge WebDriver实例
driver = webdriver.Edge(service=webdriver_service, options=edge_options)
print("等待登录")
此时运行代码,跳转出浏览器页面就代表创建成功了
指定学习通网址并打开页面进行手动登录
url = 'https://www.yuketang.cn/v2/web/index'
driver.get(url)
此时会打开登录首页,需自行扫码登录
通过检测元素找到课程链接
学过爬虫的肯定对selenium不陌生,他可以根据元素属性找到元素,这里我们就要用到它以完成查找、点击的操作
判断上课状态
def fresh_bug():
WebDriverWait(driver, 1.5).until(
EC.presence_of_element_located(
(By.XPATH, '//*[@id="pane--1"]/div/section[1]/div[2]/div[2]/section/div[1]/div/div/span'))
)
定义一个通过XPath寻找上课标识的函数,以备之后使用,标识如图所示
当能找到这个标识,即说明上课了,反之则反
找到科目元素
try:
# 等待并点击tab-student标签
print("等待 tab-student 出现")
tab_student_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, 'tab-student'))
)
tab_student_element.click()
print("课程主界面点击完成")
print("等待对应课程元素 H1 出现")
h1_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//h1[contains(text(), 'test')]"))# 这里输入课程信息
)
h1_element.click()
print("课程元素点击成功")
登录并进入主页的时候默认是“我教的课”选项,而我们需要进入的是“我听的课”界面。
这就是ID为tab-student的元素,如代码所示
进入之后需要找到自己需要签到的课,如代码中的test就是我用的测试课程名,当然,课程的老师名或者备注等都可以替换为关键文本。代码会根据你输入的内容查找文本位置并点击,建议看一下有没有什么文本冲突:如课程名一样但老师不是同一个就可以输入老师名。
一是避免同时查找到相同属性的课程卡片
二是方便切换
验证上课状态的刷新bug
while True:
print("判断是否上课")
try:
print("检测 span 标签中")
fresh_bug()
print("首次检测成功")
driver.refresh()
print("刷新并重新检测")
fresh_bug()
print("再次检测成功")
# 由于雨课堂有时候会出现bug:没有上课却刷新出上课的标志,此段代码用于双重校检
看最后一段while,try的第一段进行了两次刷新,因为雨课堂刷新的时候会有几率遇到bug,就是明明没上课却显示上课标识,如果把这段双重校检去掉,遇到这个bug就会退出程序但实际没有签到。
当检测到标识出现时,会再次刷新,如果标识还在,即说明是真正的上课了,执行点击指令。
如果再次刷新后上课标识不再出现,则说明遇到了bug,重新进入循环。
可以把这段多复制几次,消耗的时间较短并不影响。
重复操作第一个课程
以此不停刷新直到课程开启
print("等待 Section 元素出现")
section_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH,
'/html/body/div[4]/div[2]/div/div/div[2]/div[2]/div[2]/div[2]/div[2]/div[1]/div/section[1]/div[2]/div[2]/section/div[1]'))
)
section_element.click()
print("Section 元素点击成功")
break
except Exception as e:
print("未找到特定的上课标识")
driver.refresh()
print("刷新完成")
continue
except Exception as e:
print(f"发生错误: {e}")
最后就是找到并验证标识之后则点击课程,这里的Xpath地址代表的是一排所有课程的第一个卡片
最后,代码中任何有关时间的包括timeout(超时)等方法可以自行修改。决定了操作的时间限制,如果遇到网速不好的情况,可以把时间拉长,避免还没登录就自动报错退出程序或者其他操作被中断的情况。
如果觉得浪费资源可以使用schedule库用来定时执行某些指令,这里就不写了
然后修改一些参数(文件地址、科目名字等),启动程序并登录好后,就可以安心地去睡觉了,明天的早八交给它吧。
完整代码
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
edge_options = Options()
edge_options.add_experimental_option("detach",True)
# 设置EdgeDriver路径
webdriver_service = Service('E:\\box\\pachong\\msedgedriver.exe') # 替换为您的EdgeDriver路径
# 创建Edge WebDriver实例
driver = webdriver.Edge(service=webdriver_service, options=edge_options)
print("等待登录")
# 打开网页
url = 'https://www.yuketang.cn/v2/web/index'
driver.get(url)
def fresh_bug():
WebDriverWait(driver, 1.5).until(
EC.presence_of_element_located(
(By.XPATH, '//*[@id="pane--1"]/div/section[1]/div[2]/div[2]/section/div[1]/div/div/span'))
)
try:
# 等待并点击tab-student标签
print("等待 tab-student 出现")
tab_student_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, 'tab-student'))
)
tab_student_element.click()
print("课程主界面点击完成")
print("等待对应课程元素 H1 出现")
h1_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//h1[contains(text(), 'test')]"))
)
h1_element.click()
print("课程元素点击成功")
while True:
print("判断是否上课")
try:
print("检测 span 标签中")
fresh_bug()
print("首次检测成功")
driver.refresh()
print("刷新并重新检测")
fresh_bug()
print("再次检测成功")
# 由于雨课堂有时候会出现bug:没有上课却刷新出上课的标志,此段代码用于双重校检
print("等待 Section 元素出现")
section_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH,
'/html/body/div[4]/div[2]/div/div/div[2]/div[2]/div[2]/div[2]/div[2]/div[1]/div/section[1]/div[2]/div[2]/section/div[1]'))
)
section_element.click()
print("Section 元素点击成功")
break
except Exception as e:
print("未找到特定的上课标识")
driver.refresh()
print("刷新完成")
continue
except Exception as e:
print(f"发生错误: {e}")
若有错误或优化建议希望大佬指出