对中国大学MOOC课程视频批量下载的探索

声明:请尊重各大高校对慕课内容的版权,下载慕课视频仅为方便自己学习使用,请勿肆意传播或用于商业用途。一切因滥用下载所得慕课内容所产生的法律问题本人概不负责。

中国大学MOOC是一个公益性质的免费慕课平台,由各大高校共享自己的课程内容。虽然在这些慕课中有相当大一部分是全程念ppt的敷衍之作,但是也不乏一些制作精良、讲解用心的精品慕课。然而网易的这个HTML5播放器做得实在太烂,经常会出现两重声音,倍速错乱等各种bug,快进快退也很不方便,非常影响观看体验。IDM自带的流媒体探测功能虽然可以直接下载播放页面中的慕课视频,但是一集一集地下载费时费力,还需要为每一个下载的文件重命名,于是我萌生了批量下载课程视频的想法。

首先检查播放页面中的HTML5播放器元素,发现了视频资源的URL。



但是查看网页源代码的时候却并没有发现与HTML5播放器有关的内容,看来这是一个由js即时生成网页内容的动态网页。我技术有限,暂时还不会从动态网页上抓取内容的操作。而且若要通过获取视频播放页面中视频的URL来实现批量下载的话,需要遍历该课程的所有播放页面,非常繁琐。

直接从Web页面抓取下载链接的方法过于繁琐,于是我将目光投向了手机客户端。




为了效率,手机客户端与服务器间一般以简单易懂的json等方式进行通讯,我希望能从手机客户端与服务器的报文中获取有价值的信息。手机抓包的方法有很多,出于个人习惯,这里我选择了在PC上使用Fiddler 4进行抓包。在手机客户端登陆账号,打开对应课程,Fiddler中立刻出现了客户端与服务器通讯的报文。




经过仔细查看,终于在目的为www.icourse163.org/mob/course/courseLearn/v1的POST方法的response内容中发现了有用信息。

将这一报文复制出来,发现这是一份包含该课程的所有信息以及各个视频的源文件URL的json。将这份json格式化之后,我们可以清晰地看到它的层次结构。



“results”下的”courseDto”包含了当前课程的名称、学校名称、简介等各种信息,”termDto”包含了章节(”chapters”)课时(”lessons”)课的分节(”units”)这样的分层结构,在”units”下的”resourceInfo”中,就包含了这节课的标清、高清、超清资源分别对应的源文件URL。得到了这份json后,我们就可以根据其结构编写代码来批量下载它们,这里我使用Python。

[python] view plain copy
print ?
  1. # -*- coding: utf-8 -*-  
  2. import json  
  3. import os  
  4. import urllib.request  
  5. jsonFile=open(’json.txt’).read()#事先将抓包所得的json保存为同目录下的文本文件  
  6. jsonObj=json.loads(jsonFile)  
  7. def Schedule(a,b,c):#下载进度指示  
  8.     ””’ 
  9.     a:已经下载的数据块 
  10.     b:数据块的大小 
  11.     c:远程文件的大小 
  12.    ”’  
  13.     per = 100.0 * a * b / c  
  14.     if per > 100 :  
  15.         per = 100  
  16.     print(‘%.2f%%’ % per)  
  17. def getMOOCLessons(jsonObj):  
  18.     courseName=jsonObj[’results’][‘courseDto’][‘name’]+“ ”+jsonObj[‘results’][‘courseDto’][‘schoolName’]  
  19.     os.mkdir(courseName)#创建名称为“课程名+校名”的根目录  
  20.     chapters=jsonObj[’results’][‘termDto’][‘chapters’]#读取所有章节的信息为一个列表  
  21.     for i in range(len(chapters)):#遍历所有章节  
  22.         os.mkdir(courseName + ’\\’ + chapters[i][‘name’])#每一个章节建立一个文件夹  
  23.         print(chapters[i][‘name’])  
  24.         lessons=chapters[i][’lessons’]#读取当前章节下所有课时的信息为一个列表  
  25.         for j in range(len(lessons)):#遍历所有课时  
  26.             units=lessons[j][’units’]#读取当前课时下所有小节的信息为一个列表  
  27.             for k in range(len(units)):#遍历所有小节  
  28.                 aunit=units[k]  
  29.                 if (aunit[“contentType”]==1):#判断该小节是否为视频内容  
  30.                     print(“Downloading ”+aunit[‘name’])  
  31.                     urllib.request.urlretrieve(aunit[”resourceInfo”][“videoHDUrl”], courseName + ‘\\’ + chapters[i][‘name‘]+’\\‘+aunit[‘name’]+“.mp4”, Schedule)#下载文件,这里下载的是高清资源  
  32. getMOOCLessons(jsonObj)  
# -*- coding: utf-8 -*-
import json
import os
import urllib.request
jsonFile=open('json.txt').read()#事先将抓包所得的json保存为同目录下的文本文件
jsonObj=json.loads(jsonFile)
def Schedule(a,b,c):#下载进度指示
    '''''
    a:已经下载的数据块
    b:数据块的大小
    c:远程文件的大小
   '''
    per = 100.0 * a * b / c
    if per > 100 :
        per = 100
    print('%.2f%%' % per)
def getMOOCLessons(jsonObj):
    courseName=jsonObj['results']['courseDto']['name']+" "+jsonObj['results']['courseDto']['schoolName']
    os.mkdir(courseName)#创建名称为“课程名+校名”的根目录
    chapters=jsonObj['results']['termDto']['chapters']#读取所有章节的信息为一个列表
    for i in range(len(chapters)):#遍历所有章节
        os.mkdir(courseName + '\\' + chapters[i]['name'])#每一个章节建立一个文件夹
        print(chapters[i]['name'])
        lessons=chapters[i]['lessons']#读取当前章节下所有课时的信息为一个列表
        for j in range(len(lessons)):#遍历所有课时
            units=lessons[j]['units']#读取当前课时下所有小节的信息为一个列表
            for k in range(len(units)):#遍历所有小节
                aunit=units[k]
                if (aunit["contentType"]==1):#判断该小节是否为视频内容
                    print("Downloading "+aunit['name'])
                    urllib.request.urlretrieve(aunit["resourceInfo"]["videoHDUrl"], courseName + '\\' + chapters[i]['name']+'\\'+aunit['name']+".mp4", Schedule)#下载文件,这里下载的是高清资源
getMOOCLessons(jsonObj)


执行这段Python程序即可自动批量下载慕课视频,因为下载耗时很长,我在这里将它丢到了树莓派上执行,最终按照预想生成了对应的目录结构并成功下载课程全部视频。




这里只是简单地实现了功能,如果想提高效率可以进一步将程序改为多线程执行。

http://blog.csdn.net/wxyedward/article/details/79080246

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值