吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11669|回复: 36
收起左侧

[Python 转载] 刷网课,应该能实现

  [复制链接]
山野村夫-陈墨 发表于 2020-3-14 22:02
新冠肺炎可怕,增加网课头大。
selenium强大,解决了它。


一、功能描述:
      目标: 超星平台 新型冠状病毒防疫公益课或和其他网页结构内类似的课
  软件环境: python3 +  selenium + chrome+ chromedriver

二、程序完整版( yun_code 是云打码的接口 )
[Python] 纯文本查看 复制代码
"""    通过selenium 实现刷课程序
        超星平台
    url: http://passport2.chaoxing.com/login?fid=&refer=http://i.mooc.chaoxing.com
"""
from  selenium  import webdriver
import  requests
import  yun_code
import  time
import  random
import  easygui as g

class  chaoxing_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 in  ans.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 in  ans_cookies:
            self.driver.add_cookie( item  )
        # 8、登录
        self.driver.find_element_by_xpath("//*[@id='form']/table/tbody/tr[7]/td[2]/label/input").click()


    # 登录账号、对外接口
    def sign(self):
        for i in  range(10):
            print("第{}登录。。。。".format( i+1 ))
            try:
                self._sign()
                print("\t登录成功!")
                return True
            except :
                time.sleep(1)
        return  False

    # 选择课程, 返回当前课程地址
    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[0]) 切换到最前的一页
        ##  todo 解决问题: 点击超链接( target="_blank")后current_url 和page_souce本页没有改变
        self.driver.switch_to.window(self.driver.window_handles[1])
        print("\t选择成功!")
        return  self.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[5]/div[1]/div[2]/div[3]/div[1]/div[1]/h3/span[3]/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[2]").text
            # print( ans )
            if ans:
                for i in  range(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
            except  Exception as e:
                time.sleep(1)
        return ""


    # 看视频
    def  view_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 in  iframe:
            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[4]/div[4]/span[2]").text
                    time_num =  int(str(time_leng).split(":")[0].strip())*60 + int(str(time_leng).split(":")[1].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 )
            if  video_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[0]
        password = ans[1]
        school_name = ans[2]
        class_name = ans[3]
        spider = chaoxing_spider( account ,password , school_name, class_name )
        spider.run()


三、一点反思:
     (1)iframe 、frame 框架的嵌套。
[HTML] 纯文本查看 复制代码
<body>
        <iframe id="iframe_id"    src=“iframe_url”>
               <input  id="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[0]) 切换到最前的一页
               
     (3)加载未完成执行操作,报错
              ①执行点击查找之前进行一次webdruiver.get(),  因为它是加载完之后执行后面程序
              ②延迟;强制延时,time.sleep();   (貌似没用)显式等待;隐式等待。
  
   

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
laotun + 1 + 1 我很赞同!
穆萨 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时间的代码,然后把播放时间写入最后一秒,就能秒过一节课了。多年前上大学,花了一小时过了两门公开课~
 楼主| 山野村夫-陈墨 发表于 2020-3-20 18:44
jidesheng6 发表于 2020-3-19 21:44
膜拜大佬,真是苦了你了,超星平台太贱了

平台太挺好,给大家提供了一个学习的平台。  只是学校太贱了,安排一些莫名其妙的杂课。
学吧,都是一些冠冕堂皇的废话,华而不实。 不学吧,学分放在那儿
asdcy2003 发表于 2020-3-14 22:51
求成品  最好能适应 现在所有 网课天天挂科 太累
橡鳄君 发表于 2020-3-14 22:52
刷了后台能查出来的,
alanye 发表于 2020-3-14 22:59
其实我觉得刷网课这种行为并不好,对自己没有好处。况且老师可以在后台看到的。
729 发表于 2020-3-14 23:01
SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时 ...

求技术  嘿嘿 这个感觉好玩
纣王妲己 发表于 2020-3-14 23:23
SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时 ...

现在秒过不行了 隔了一个月红信要求重看  现在暴力猴解决
 楼主| 山野村夫-陈墨 发表于 2020-3-14 23:25
SQ-Will 发表于 2020-3-14 22:38
超星的视频很多看一半要做题才能继续的,而且挂着浪费时间,浪费电。可以劫持下播放器,nop掉播放器控制时 ...

你的意思就是后台的观看时间是浏览器直接反馈,而不是做个时间差?
 楼主| 山野村夫-陈墨 发表于 2020-3-14 23:27
asdcy2003 发表于 2020-3-14 22:51
求成品  最好能适应 现在所有 网课天天挂科 太累

我会把这个代码加工完善, 但是不会发出来。
不太好,我觉得
 楼主| 山野村夫-陈墨 发表于 2020-3-14 23:29
橡鳄君 发表于 2020-3-14 22:52
刷了后台能查出来的,

有些课,实在就是折磨人。 上,浪费时间、精力,不上还不行。只能刷了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-30 13:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表