刷网课,应该能实现
新冠肺炎可怕,增加网课头大。selenium强大,解决了它。
一、功能描述:
目标: 超星平台 新型冠状病毒防疫公益课或和其他网页结构内类似的课
软件环境: python3 +selenium + chrome+ chromedriver
二、程序完整版( yun_code 是云打码的接口 )
""" 通过selenium 实现刷课程序
超星平台
url: http://passport2.chaoxing.com/login?fid=&refer=http://i.mooc.chaoxing.com
"""
fromseleniumimport webdriver
importrequests
importyun_code
importtime
importrandom
importeasygui as g
classchaoxing_spider():
def __init__(self,user_name, user_password, school_name,class_name):
self.url = "http://passport2.chaoxing.com/login?fid=&refer=http://i.mooc.chaoxing.com"
self.user_name = user_name
self.user_password = user_password
self.school_name = school_name
self.class_name = class_name
#设置无界面参数
# 创建chrome参数对象
chrome_options = webdriver.ChromeOptions()
#chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox') # 非沙盒模式
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-dev-shm-usage')
self.driver = webdriver.Chrome( options=chrome_options , executable_path="Chrome/chromedriver.exe")
print("运行")
#登录账号细节
def _sign(self):
self.driver.get( self.url )
# 1、获取验证码url,返回图片内容和cookies
img = self.driver.find_element_by_id("numVerCode").get_attribute("src")
# 2、请求验证码url
ans = requests.get( img )
# 3、照片cookies
ans_cookies= []
for item inans.cookies:
ans_cookies.append({'name':item.name , 'value':item.value} )
# 4、将验证码写到jpg里
with open(b"file/011.jpg", "wb")as f:
f.write( ans.content)
# 5、利用云打码获取验证码
code= yun_code.get_code( 1004,b'file/011.jpg')
# 选择学校
self.driver.find_element_by_link_text("选择单位").click()
self.driver.find_element_by_id("searchSchool1").send_keys(self.school_name )
self.driver.find_element_by_class_name("zw_t_btn").click()
#此处有加载过程,需要尝试
for i in range(10):
try:
self.driver.find_element_by_link_text( self.school_name).click()
break
except :
time.sleep(1)
#填写账号、密码、验证码
self.driver.find_element_by_id("unameId").send_keys( self.user_name)
self.driver.find_element_by_id("passwordId").send_keys( self.user_password)
# 6、填写验证码
self.driver.find_element_by_id("numcode").send_keys( code )
# 7、将验证码cookies添加到driver
for item inans_cookies:
self.driver.add_cookie( item)
# 8、登录
self.driver.find_element_by_xpath("//*[@id='form']/table/tbody/tr/td/label/input").click()
# 登录账号、对外接口
def sign(self):
for i inrange(10):
print("第{}登录。。。。".format( i+1 ))
try:
self._sign()
print("\t登录成功!")
return True
except :
time.sleep(1)
returnFalse
# 选择课程, 返回当前课程地址
def selected_class(self):
print("选择课程。。。。。")
self.driver.get(self.driver.current_url )
#切换到iframe
for i in range(10):
try:
self.driver.switch_to.frame("frame_content")
except :
time.sleep(1)
# 发现课程,点击课程
self.driver.find_element_by_partial_link_text(self.class_name ).click()
# self.driver.get(self.driver.current_url )
##n = window.handle 获取当前页面左右的句柄
##switch_to_window( n) 切换到最前的一页
##todo 解决问题: 点击超链接( target="_blank")后current_url 和page_souce本页没有改变
self.driver.switch_to.window(self.driver.window_handles)
print("\t选择成功!")
returnself.driver.current_url
# 获取某一章节的视频url
def open_class(self, url ):
self.driver.get( url )
self.driver.refresh() # 更新界面
time.sleep( 2 )
self.driver.find_element_by_xpath("*//div/div/div/div/div/div/h3/span/a") .click()
# 获取 章节对象
part_list = []
part_list = self.driver.find_elements_by_xpath(" //*[@id='coursetree']//h4")
for item in part_list:
ans = item.find_element_by_xpath("span").text
# print( ans )
if ans:
for i inrange(5):
try:
item.find_element_by_xpath("a").click()
print("章节:",str(item.find_element_by_xpath("*//span").text).strip() )
break
except:
time.sleep(1)
break
# 获取当页视频、有加载过程,需要等待
for i in range(10):
try:
video__url = self.driver.find_element_by_xpath("*//iframe[@id='iframe']").get_attribute("src")
return video__url
exceptException as e:
time.sleep(1)
return ""
# 看视频
defview_video(self, url ):
self.driver.get(url )
iframe=[]
for i in range(10):
iframe = self.driver.find_elements_by_xpath("*//iframe")
if iframe:
break
time.sleep(1)
# 如果是图片,则不存在iframe
if not iframe:
print("这是图片,不看了")
return
index = 1
for item iniframe:
self.driver.switch_to.frame( item )
print("\t正在看第{}个视频".format(index ))
for i in range(10):
try:# todo 这个切换一定注意
self.driver.find_element_by_xpath("*//div[@id='reader']").click()
time.sleep(1)
# 视频时长
time_leng =self.driver.find_element_by_xpath("//*[@id='video']/div/div/span").text
time_num =int(str(time_leng).split(":").strip())*60 + int(str(time_leng).split(":").strip())
print("\t\t时长:", time_num)
time.sleep( int(time_num) )
break
except Exception as e:
print(i,e)
time.sleep(1)
print("\t\t第{}个视频结束了".format( index ) )
# 回到默认页面
self.driver.switch_to.default_content()
index +=1
# 逻辑实现
def run(self):
if not self.sign():
print("登录失败!")
return
class_url = self.selected_class()
while True:
video_url = self.open_class( class_url )
ifvideo_url:
self.view_video( video_url )
time.sleep( random.randint(1,10))
else:
break
if __name__ == '__main__':
ans = g.multenterbox(msg='输入信息!', fields=['账号','密码','学校信息','课程'],
values=["账号","密码", "学校名称","新型冠状病毒"])
if len(ans)== 4:
account = ans
password = ans
school_name = ans
class_name = ans
spider = chaoxing_spider( account ,password , school_name, class_name )
spider.run()
三、一点反思:
(1)iframe 、frame 框架的嵌套。
<body>
<iframe id="iframe_id" src=“iframe_url”>
<inputid="input_id"/>
</iframe>
</body>
这种情况下执行 webdriver.find_element_by_id("input_id")必然报错, 因为 input_id 在iframe 中,而不在当前文档中。
①用webdriver.switch_to_frame( “frame_id”) 切换到iframe, 此时的webdriver的文档iframe文档, 但是这个有个加载过程,需要延时。之后webdriver.find_element_by_id("input_id")。
②获取iframe的url, webdriver.get( iframe_url), 此时的页面就是ifram的页面。直接操作webdriver.find_element_by_id("input_id")。
ps: 如果采用①,应该记得返回主文档, 来一句webdriver.switch_to_default_content().
(2)<a href=""target="_BLANK">超链接的跳转。
此时点击超链接,虽然页面跳转了 , 但是webdriver.page_course 和webdriver.current_url 还是原来的,并不是超链接跳转之后的。解决这个问题的方法:
n = window.handle 获取当前页面左右的句柄switch_to_window( n) 切换到最前的一页
(3)加载未完成执行操作,报错
①执行点击查找之前进行一次webdruiver.get(),因为它是加载完之后执行后面程序
②延迟;强制延时,time.sleep(); (貌似没用)显式等待;隐式等待。
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时间的代码,然后把播放时间写入最后一秒,就能秒过一节课了。多年前上大学,花了一小时过了两门公开课~ jidesheng6 发表于 2020-3-19 21:44
膜拜大佬,真是苦了你了,超星平台太贱了
平台太挺好,给大家提供了一个学习的平台。只是学校太贱了,安排一些莫名其妙的杂课。
学吧,都是一些冠冕堂皇的废话,华而不实。 不学吧,学分放在那儿 求成品最好能适应 现在所有 网课天天挂科 太累 刷了后台能查出来的, 其实我觉得刷网课这种行为并不好,对自己没有好处。况且老师可以在后台看到的。 SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时 ...
求技术嘿嘿 这个感觉好玩 SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时 ...
现在秒过不行了 隔了一个月红信要求重看现在暴力猴解决
SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时 ...
你的意思就是后台的观看时间是浏览器直接反馈,而不是做个时间差? asdcy2003 发表于 2020-3-14 22:51
求成品最好能适应 现在所有 网课天天挂科 太累
我会把这个代码加工完善, 但是不会发出来。
不太好,我觉得 橡鳄君 发表于 2020-3-14 22:52
刷了后台能查出来的,
有些课,实在就是折磨人。 上,浪费时间、精力,不上还不行。只能刷了