newversion=true
启动新版页面loginType
是url中用来指定登陆方式的,其中默认是1,手机号密码登陆;2位手机号验证码登陆;3位学号密码登陆,但是3加入的验证码,我们需要用到一些打码平台,所以自动登陆时会有一定成本,再次看来第一种手机密码登陆为最优登陆方式Selenium
库来启动浏览器,如果想要了解selenium库可以看我之前写的一片博客selenium库使用方法。功能还不完善,等之后有空会完善一下
import time
from bs4 import BeautifulSoup
from selenium import webdriver
# 行为链
from selenium.webdriver.common.action_chains import ActionChains
class AutoClassroom:
def __init__(self, user='寻觅最帅', pd='寻觅我爱你', classroom=None):
# 登陆网址传入参数logintype的值为:1手机号密码登陆,2手机号验证码登陆,3学号密码登陆(第三种方式有验证码,每次登陆需要一定成本,不建议使用)
self.login_url = 'https://passport2.chaoxing.com/login?newversion=true&loginType={}'
# 用户名
self.login_user = user
# 登陆密码
self.login_password = pd
# 课名
self.classroom = classroom
# 浏览器对象
self.driver = None
def start_web(self):
"""启动浏览器"""
# 我的电脑上用的是火狐浏览器与其配套的插件
# 先加载火狐的插件
config = webdriver.FirefoxProfile(r"C:\Users\fan45\AppData\Roaming\Mozilla\Firefox\Profiles\pfv6rlbm.default-release")
self.driver = webdriver.Firefox(config)
# self.driver.set_window_position(400, 3)
# 学习通服务器不好,隐式睡眠等待服务器响应
self.driver.implicitly_wait(3)
# 改变浏览器窗口大学
# self.driver.minimize_window()
def login(self, mode=1):
"""登陆模块"""
# mode为预留登陆模式接口
self.driver.get(self.login_url.format(mode))
# 手机号登陆输入框
phone = self.driver.find_element_by_id('phone')
phone.send_keys(self.login_user)
# 密码输入框
password = self.driver.find_element_by_id('pwd')
password.send_keys(self.login_password)
# 登陆按钮
click = self.driver.find_element_by_id('loginBtn')
click.click()
def seek_classroom(self):
"""寻找课程"""
# 进入到frame嵌入页面
self.driver.switch_to.frame('frame_content')
room = self.driver.find_element_by_xpath(f'//*[@title="{self.classroom}"]')
room.click()
# 退回到父页面
self.driver.switch_to.parent_frame()
# 获取新开启的页面的页柄
time.sleep(1)
return self.driver.window_handles[1]
def look_classroom(self, handles):
"""观看课程"""
# 新建一个焦点(之后使用到多线程,如果都使用共同的driver会造成共享资源阻塞等问题)
driver = self.driver
# 启动隐式等待(这里嵌套网页较多,且学习通服务器并不是很好)
driver.implicitly_wait(10)
# 将焦点定位到此页面中
driver.switch_to.window(handles)
# 进入到课程页面(这里需要模仿鼠标点击),启用行为链
classroom_html = driver.find_element_by_xpath('//span[@class="articlename"]/a')
# 实例化鼠标
mouse = ActionChains(driver)
# 寻找确定点击目标
mouse.click(classroom_html)
# 执行操作
mouse.perform()
# 获取所以课程列表
timetable = driver.find_elements_by_class_name('ncells')
# 遍历所有课程
for classroom in timetable:
# 点击课程
classroom.click()
room = self.driver.find_element_by_xpath('//*[@title="视频"]')
# 如果不包含视频则跳出
if room is None:
break
room.click()
# 视频采用嵌入式页面
driver.switch_to.frame('iframe')
driver.switch_to.frame(driver.find_element_by_class_name('ans-attach-online'))
driver.find_element_by_xpath('//button[@title="播放视频"]').click()
# 返回父页面
driver.switch_to.parent_frame()
driver.switch_to.parent_frame()
# 网课插件会播放下一集,这里第一版就不考虑如果切换下一集了。
break
def run(self):
"""运行模块"""
# 启动浏览器
print('启动浏览器中')
self.start_web()
# 登陆
print('正在登陆')
self.login()
# 寻找课程(新课程会获取新的页面)
print('寻找指定课程')
handles = self.seek_classroom()
# 观看课程
print('开始观看中')
self.look_classroom(handles)
if __name__ == '__main__':
user = input('请输入学号或手机号:')
pd = input('请输入密码:')
classroom = input('请输入想要观看的课程:')
AutoClassroom().run()