前(废)言(话)
好慕课(haomooc)是一个全学科,综合性的慕课导航平台。平台课程包含大学,中小学以及技能培训等。好慕课内所有同步视频课程免费。
好慕课算是一个比较良心的慕课平台了,里面的视频资源非常全面。然而,其线上观看的播放器较为简陋,不尽人意。
于是编写脚本,尝试将好慕课的视频批量下载下来。
过程实现
视频地址获取
通过抓包发现,其中加载了一个m3u8文件:
而且每次刷新后,m3u8文件的地址随之改变,猜测其m3u8文件是有有效期的。
分析源代码可知,m3u8文件的动态地址已经写在<video></video>中。
那就正则匹配出来呗:
import requests
import re
i = 'https://haomooc.com/index.php?s=xiaoxue&c=show&id=495&dezhi=1' #要抓取的网址
html = requests.get(i,headers = hea)
html.encoding = 'utf-8'
#此为正则表达式部分。找到规律,利用正则,内容就可以出来
M3u8 = re.findall('<source src="(.*?)" type="application/x-mpegURL">',html.text,re.S)
#正则匹配`<source src="`到`" type="application/x-mpegURL">`的文本。
获取一季视频的列表
发现前面都带有<a href="index.php?s=
,但是搜索得知,在最上面还有一个与我们需要内容无关的项,如果使用正则匹配后不进行筛选,会混入很多无用内容。
正则匹配后筛选列表中含有sectionid
字样的元素,以保证筛选到的都是正常的URL:
print ('获取列表……')
html = requests.get(Url0,headers = hea)
html.encoding = 'utf-8' #这一行是将编码转为utf-8否则中文会显示乱码。
href = re.findall('<a href="index.php?(.*?)" ',html.text,re.S) #正则匹配所有`<a href="index.php?s=`到`" `的内容
href = [s for s in href if 'sectionid' in s] #筛选列表中含有`sectionid`字样的元素
此时以上列表href
的内容是:
xiaoxue&c=show&packid=100330§ionid=2311
xiaoxue&c=show&packid=100330§ionid=2269
xiaoxue&c=show&packid=100330§ionid=2278
xiaoxue&c=show&packid=100330§ionid=2292
…
补充上前缀就完整了。
那么主体部分基本完成。
视频下载部分
干脆用一个别人做好的批量m3u8下载器,何乐而不为。(点我跳转到原网站)
按调用格式,将获取到的m3u8地址逐行写入文件,最后运行os.system()进行调用就OK了。
问题
emmm,获取到的m3u8文件大概只有5-10分钟左右的有效期,当一次性获取过多m3u8地址时,前面的还没下载完后面的m3u8文件就过期了,目前的解决方法:分区间下载,或者你手动修改源码让它每获取20个文件隔五分钟再接下去获取也可以。
源码和成品下载
本地下载(慢)
Onedrive下载
源码(Python3.x环境 请提前安装requests
库,并下载M3u8下载器):
import requests
import re
from os import system
num = 0
with open('URLURL.txt','w',encoding='utf-8') as f:
print('文件已创建')
Url0 = input("Give me a Haomooc Url : ")
#hea是我们自己构造的一个字典,里面保存了user-agent。
#让目标网站误以为本程序是浏览器,并非爬虫。
#从网站的Requests Header中获取。【审查元素】
hea = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36'}
print ('获取列表……')
html = requests.get(Url0,headers = hea)
html.encoding = 'utf-8' #这一行是将编码转为utf-8否则中文会显示乱码。
#此为正则表达式部分。找到规律,利用正则,内容就可以出来
href = re.findall('<a href="index.php?(.*?)" ',html.text,re.S)
href = [s for s in href if 'sectionid' in s] #筛选好慕课URL部分
start = input ('共有'+str(len(href))+'个视频。从哪个开始?')
stop = input ('从第'+str(start)+'个视频开始。到哪个结束?')
num = 0 + int(start) - 1
print ('正在下载从第' + start +'个视频到第' + stop +'个视频的m3u8文件信息。')
'''
num_tit = 0
for tit in href:
num_tit = num_tit + 1
print ('[' + str(num_tit) + ']' + tit)
'''
'''
if int(stop)==len(href):
href = href[int(start)-1:int(stop)]
else:
'''
href = href[int(start)-1:int(stop)]
for i in href:
i = 'https://haomooc.com//index.php' + i
#print (i)
html = requests.get(i,headers = hea)
html.encoding = 'utf-8'
#此为正则表达式部分。找到规律,利用正则,内容就可以出来
title = re.findall('<title>(.*?)-好慕课</title>',html.text,re.S)
M3u8 = re.findall('<source src="(.*?)" type="application/x-mpegURL">',html.text,re.S)
num = num + 1
xuhao = str(num) + '-'
all_info = xuhao + title[0]+','+M3u8[0]
print (all_info)
with open('URLURL.txt','a+',encoding='utf-8') as f:
f.write(all_info + '\n')
system('m3u8.exe URLURL.txt')
print ()
print ('M3U8信息下载完成,已向下载器提交下载信息。')
print ()
system('pause')
0 条评论