爬取新闻直播间快讯

文章目录

  • 写在前面
  • 用到的包
  • 主要代码
  • 如何使用
  • 写在后面

写在前面

昨天上班的时候老哥问我能不能把cctv的视频下载下来,本着能播放就能下载的原则,我打开了F12。。。想获得完整的视频下载地址是有些难度的,不过把所有的视频流按顺序写进同一个二进制文件也是可行的办法。顺便尝试了一下从命令行获取参数,以及在下载过程中使用进度条。

用到的包

#爬取模块
import requests
#正则表达式、文件夹、系统变量
import re,os,sys
#进度条相关
from tqdm import tqdm

主要代码

根据参数获取url地址(这里提供一个url样例,是播放页面的地址)

if len(sys.argv) == 2:
    url = sys.argv[1]
else:
    sys.exit()
    #url = 'https://tv.cctv.com/2020/11/26/VIDEkd2TSFPv3uK8Ias25jYL201126.shtml?spm=C28340.P1dzdfA9CsHZ.S29237.42'

浏览器标识(请求头),并创建“新闻联播”文件夹

headers = {
     
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
    }

if not os.path.exists('新闻联播'):
    os.mkdir('新闻联播')
os.chdir('新闻联播')

获取guid和视频标题

def GetInfo():
    try:
        #请求视频地址,并编码为utf-8
        req = requests.get(url = url,headers = headers)
        req.encoding = 'utf-8'
        #正则匹配guid(视频唯一标识符)
        pattern_guid = re.compile('var\sguid\s=\s"(.*?)";')
        #正则匹配网页中的视频标题
        pattern_title = re.compile('var\scommentTitle\s=\s"(.*?)";')
        guid = re.findall(pattern_guid,req.text)[0]
        title = re.findall(pattern_title,req.text)[0].replace('/','')
        #返回获取到的信息
        return guid,title
    except:
        #如果出现异常则返回None
        return None,None

获取视频流的总段数,并按顺序写进二进制文件

#guid,title为上面函数获取到的信息
def GetVideo(guid,title):
    try:
        #拼接出保存视频流信息文件的url地址(将花括号替换为了guid)
        ts_list_url = "https://hls.cntv.lxdns.com/asp/hls/850/0303000a/3/default/{}/850.m3u8?maxbr=2048".format(guid)
        #请求目标地址
        req_ts = requests.get(url = ts_list_url,headers = headers)
        #正则匹配,查询返回信息中共有多少个“.ts”
        pattern_ts = re.compile("\.ts")
        num = len(re.findall(pattern_ts,req_ts.text))
        #创建二进制文件,根据title命名
        f = open(title + '.mp4','wb')
        print(title)
        """
        调用进度条模块写循环,保存每一段视频流
        desc为进度条的自定义提示信息,ncols为进度条长度
        """
        for i in tqdm(range(num),desc = '正在下载...',ncols=80):
            #拼接视频流的url,将两个花括号分别替换为guid、当前循环的i值
            #中间的2000代表清晰度,即2k高清,其他选项有480、720、1200
            ts_url = "https://hls.cntv.lxdns.com/asp/hls/2000/0303000a/3/default/{}/{}.ts".format(guid,i)
            #请求与写入
            req = requests.get(url = ts_url,headers = headers)
            f.write(req.content)
        #解除文件占用
        f.close()
        return 0
    except Exception as e:
        #返回错误信息
        return e

调节程序的运行并捕捉错误

def run():
    #调用函数获取guid和title
    guid,title = GetInfo()
    #如果返回值不是None
    if guid and title:
        #下载视频并捕捉返回值
        debug = GetVideo(guid, title)
        #如果返回值不是0,则打印错误信息
        if debug != 0:
            print(debug)
        #退出程序
        sys.exit()
    else:
        #如果返回值都是None,大概率是提供的url地址不对(当然也可能是网站有变动)
        print('下载失败!请检查URL地址!')
        sys.exit()
#入口函数
if __name__ == '__main__':
    run()

如何使用

#cmd下切换到py文件所在路径
python spider_cctv.py https://tv.cctv.com/2020/11/26/VIDEkd2TSFPv3uK8Ias25jYL201126.shtml?spm=C28340.P1dzdfA9CsHZ.S29237.42

写在后面

其实没有什么反爬措施,主要是在分析url,以及匹配到视频对应的guid。请勿将视频用于非法途径!

你可能感兴趣的:(笔记)