使用selenium挂超星学习通视频
in python with 0 comment

使用selenium挂超星学习通视频

in python with 0 comment

准备工作

所需要安装的环境

分析

  1. 首先我们需要先进行登陆。因为网站有验证码,而且我们主要的目的是为了能够观看视频,等视频观看完毕后,模拟点击到下一节的内容,所以这里我采用的是自己输入账号密码和验证码

            self.driver.get(self.login_url)
            WebDriverWait(self.driver, 1000).until(
                EC.url_to_be(self.initmy_url) #等待跳转到个人页面
            )
  1. 现在我们进入到个人页面后,选取要挂的网课。我这里选择的是我们学校的形势与政策的网课。所以

            WebDriverWait(self.driver, 1000).until(EC.frame_to_be_available_and_switch_to_it(
                (By.TAG_NAME, "iframe")))
            self.course_url=self.driver.find_element_by_partial_link_text('《形势与政策》2017-20...').get_attribute("href")
            self.driver.get(self.course_url)
            WebDriverWait(self.driver, 1000).until(
                EC.url_to_be(self.course_url)

这里使用driver的find_element_by_partial_link_text()这个方法,通过寻找链接内容为形势与政策的元素,并通过get_attribute方法获得他的链接然后跳转到这个链接。

  1. 接下来就是实现播放当前视频,播放完跳转到下一个视频。

分析网页后我们发现,主要有三种情况。

再进行分析后,我们发现所有有视频需要播放的页面都在一个iframe标签中,所以我们找出网页中一共有多少个iframe标签,有几个标签说明有几个视频。再对iframe进行分析,我们只要找到idreader的标签进行点击,视频就可以播放了。
请输入图片描述

视频的时长在 nameflashvars里面,使用python中的parse.unquote()对其进行解码,其中的duration就是视频时间。一个视频是这样播放的,一个for循环就可以实现同一个页面中不同视频的播放了,不过我们需要注意的是Selenium打开页面后,它默认是在父级Frame里面操作,而此时如果页面中还有子Frame,它是不能获取到子Frame里面的节点的。这时就需要使用switch_to.frame()方法来切换Frame。

不过期间出现了一个问题,就是如果在一个页面中,播放完第一个视频后虽然程序正常运行,但是剩下的几个视频竟然不播放,只有当你的鼠标向下滑动,他的视频才会加载出来。所以我们通过如下方法向下滑动页面到指定元素

xpath_button_add_crowd = "/html/body/div/div/p["+str(i+1)+"]/div/div"
scroll_add_crowd_button = self.driver.find_element_by_xpath(xpath_button_add_crowd)
self.driver.execute_script("arguments[0].scrollIntoView();", scroll_add_crowd_button)
  1. PS:以下是firefox浏览器启动自动加载 adobe flash player的一些配置,没有找到谷歌浏览器的。

    option = webdriver.FirefoxProfile()
    option.set_preference("plugin.state.flash", 2)
    self.driver = webdriver.Firefox(option)

已知的问题

默认播放的线路是本校线路,但是我们校内网好像崩了,但是我找了好久也不知道怎么来进行更换线路。
请输入图片描述

以下是参考的selenium的一些用法。

写的很不错

最后附上代码

#encoding: utf-8
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import lxml,time,json
from urllib import parse
class chaoxing(object):
    def __init__(self):
        option = webdriver.FirefoxProfile()
        option.set_preference("plugin.state.flash", 2)
        self.driver = webdriver.Firefox(option)
        self.login_url = "http://passport2.chaoxing.com/mlogin?fid=122&refer=http://i.mooc.chaoxing.com/space/index.shtml"
        self.initmy_url = "http://i.mooc.chaoxing.com/space/index.shtml"

    def login(self):
        self.driver.get(self.login_url)
        WebDriverWait(self.driver, 1000).until(
            EC.url_to_be(self.initmy_url)
        )
        soup = BeautifulSoup(self.driver.page_source,'lxml')
        # print(soup.contents)
        # nickname = soup.find('span',class_='zt_u_name').text
        # # print(nickname)
        # print("欢迎"+nickname+",如果在使用的过程中遇到问题,可以截屏报错信息。")


    def access_html(self):
        self.driver.implicitly_wait(10)
        WebDriverWait(self.driver, 1000).until(EC.frame_to_be_available_and_switch_to_it(
            (By.TAG_NAME, "iframe")))
        self.course_url=self.driver.find_element_by_partial_link_text('《形势与政策》2017-20...').get_attribute("href")
        self.driver.get(self.course_url)
        WebDriverWait(self.driver, 1000).until(
            EC.url_to_be(self.course_url)
            #进入到课程页面
        )
        html = self.driver.page_source
        Soup = BeautifulSoup(html,'lxml')
        articlenames = Soup.find('div', class_="timeline").find_all("span",class_="articlename")
        a = articlenames[0].find('a')
        href = a['href']
        self.driver.get("https://mooc1-1.chaoxing.com" + href) #进入第一个链接


    def play_video(self,unit=0):
        video = ['cur117406014', 'cur117406015', 'cur117406016', 'cur117406010', 'cur117406017', 'cur117406018','cur117405990','cur117406011', 'cur117405994', 'cur117406012', 'cur117406019', 'cur117406020', 'cur117405998', 'cur117406013', 'cur117406021', 'cur117406022','cur117406023','cur117406003']
        units = video[unit:]
        for cur in units:
            x = self.driver.find_element_by_id(cur)
            x.click()
            print("正在播放", x.text)
            time.sleep(3)
            WebDriverWait(self.driver, 1000).until(EC.frame_to_be_available_and_switch_to_it(
                (By.TAG_NAME, "iframe")))
            driver_Soup = BeautifulSoup(self.driver.page_source, 'lxml')
            iframe = driver_Soup.find_all('iframe')
            for i in range(len(iframe)):
                i = int(i)
                xpath_button_add_crowd = "/html/body/div/div/p["+str(i+1)+"]/div/div"
                scroll_add_crowd_button = self.driver.find_element_by_xpath(xpath_button_add_crowd)#这里是因为如果一个页面有三个视频,只能加载第一个视频播放,所以这里向下滑到下个视频位置就能加载了
                self.driver.execute_script("arguments[0].scrollIntoView();", scroll_add_crowd_button)
                WebDriverWait(self.driver, 1000).until(EC.frame_to_be_available_and_switch_to_it(i))
                time.sleep(5)
                reader = self.driver.find_element_by_id('reader')
                reader.click()
                print('正在播放第',i+1,'个视频')
                videoSoup = BeautifulSoup(self.driver.page_source, 'lxml')
                object = videoSoup.find('object')
                # print(object)
                data = object.find_all('param', attrs={'name': 'flashvars'})[0]
                datas = data['value'].split("&")
                # print(datas[-1])
                x = parse.unquote(datas[-1])  # 将url进行解码
                # print(x)
                dict1 = eval(x[9:])
                duration = dict1.get('duration')  # 取得当前视频的时间
                time.sleep(duration+20)
                self.driver.switch_to.parent_frame()
                print("---------------------")


            self.driver.switch_to.parent_frame()



    def click_none_video(self,num=1):
        if num =='2':
            none_video = ['cur117406006','cur117406007','cur117406008','cur117405987','cur117405989','cur117405991','cur117405992','cur117405988','cur117405993','cur117405995','cur117405996','cur117405986','cur117405997','cur117405999','cur117406000','cur117406001','cur117406002','cur117406004','cur117406005','cur117406009']
            for cur in none_video:
                x = self.driver.find_element_by_id(cur)
                x.click()
                print("正在浏览", x.text)
                time.sleep(3)
            print('所有无视频的网页已经点击完毕,正在为您跳转需要观看的视频')



    def run(self):
        self.login()
        self.access_html()
        a = input("是否需要点击无视频网页?输入1不点击,输入2则点击,默认输入不点击")
        self.click_none_video(a)
        unit_lists =["2.2.1.1 引导学生对大会和报告主题进行深度理解",
                "2.2.1.2 引导学生了解十九大的主要成果",
                "2.2.1.2 引导学生了解十九大的主要成果",
                "2.2.1.3 引导学生把握中共十九大的重大意义",
                "2.3 1 热点导读" ,
                "2 2.2.2 中国宏观经济的现状与未来走向",
                "2 2.2.2.1 引导学生准确把握中国宏观经济的现状",
                "2.2.2.2 引导学生重点把握中国宏观经济的未来走向",
                "3.2.1 努力践行社会主义核心价值观",
                "3.3 1 热点导读",
                "4.2.1 构建人类命运共同体与中国外交努力方向",
                "4.2.1.1 引导学生准确把握中国构建人类命运共同体的原因与主要做法",
                "4.2.1.2 引导学生掌握中国未来外交的努力方向",
                "4.3 1 热点导读",
                "5.2.1 习近平新时代中国特色社会主义思想的精神实质",
                "5.2.1.1 引导学生准确把握习近平新时代中国特色社会主义思想的科学内涵",
                "5.2.1.2 引导学生把握习近平新时代中国特色社会主义思想的基本方略",
                "5.2.1.3 引导学生掌握习近平新时代中国特色社会主义思想的意义",
                "5.3 1 热点导读"]
        for i,unit_list in enumerate(unit_lists):
            # print(str(i)+"---"+unit_list)
            print("{} ----- {}".format(i+1,unit_list))

        x = input("请输入序号播放,如不输入则从第一小节开始")
        if x:
            x = int(x)-1
            self.play_video(x)
        else:
            self.play_video()



if __name__ == '__main__':
    wangke = chaoxing()
    wangke.run()
Responses