zoukankan      html  css  js  c++  java
  • python之爬虫(爬取.ts文件并将其合并为.MP4文件——以及一些异常的注意事项)

    //20200115

    最近在看“咱们裸熊——we bears”第一季和第三季都看完了,单单就第二季死活找不到,只有腾讯有资源,但是要vip……而且还是国语版……所以就瞄上了一个视频网站——可以在线观看(好的动漫喜欢收藏,就想着下载,第一季第三季都找到了资源,甚至第四季都有,就没有第二季……)

    最近又正好在学python(为大数据打基础),就想着爬取视频,下面说说流程:

    首先F12检查,先看看是否是直接嵌入链接(以防真的有笨笨的web主~),然后发现没有

    然后就开始点开Networks检查抓包,发现有后缀为.m3u8的链接,就点开看了——有两层,第二层是一大堆格式化数据

    然后再看剩下的包,都是.ts文件,再以.ts文件链接比对第二个m3u8包里的东西,发现正好对应,只是要拼接字符串获取真实链接,确认了思路之后就开始上手了(只是基础爬取,还未用到线程——其实用线程池技术可以更快,毕竟ts文件很多,也未用到代理,因为数据量还不算大,而且有手动限时)

    理一下思路:

    先从视频播放界面源码中获取每一集的链接,存在列表里备用(这个是显示的)---->然后获取每一个链接对应网址的源码——里边儿有一个ckplayer的div块,里边儿有第一层m3u8的链接 ----> 用beautifulSoup获取到这个链接(这个链接返回的是一个json,用json包转格式获取到第一层链接) -----> 访问这个链接获取到第二个m3u8链接(其中要拼接字符串)----->然后访问第二个链接获取到ts视频地址信息(也要拼接字符串——拼接完成后存储到列表中备用)----->使用文件输出流将ts文件下载并存在对应文件夹内

    接下来就是等待了,等它下完,因为文件很细碎,所以耗时很久……可以考虑使用线程池改进(等我把大数据基础学完了再说,不急)

    然后在每一个ts文件夹中用windows命令copy/b *.ts video.mp4将ts文件合并为mp4文件——可以嵌入到python代码中,不过我没有bat基础,就直接手动了,也不会太困难(大功告成!)

    下面上源码:

    source code:

    #20200115
    import requests
    import json
    import time
    from bs4 import BeautifulSoup
    
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36'}
    
    location = 'https://www.****.cc'
    
    mid = "/1000k/hls"
    
    last = "/index.m3u8"
    
    url_pool = ['/dianshiju/20740/player-1-1.html',
    '/dianshiju/20740/player-1-2.html',
    '/dianshiju/20740/player-1-3.html',
    '/dianshiju/20740/player-1-4.html',
    '/dianshiju/20740/player-1-5.html',
    '/dianshiju/20740/player-1-6.html',
    '/dianshiju/20740/player-1-7.html',
    '/dianshiju/20740/player-1-8.html',
    '/dianshiju/20740/player-1-9.html',
    '/dianshiju/20740/player-1-10.html',
    '/dianshiju/20740/player-1-11.html',
    '/dianshiju/20740/player-1-12.html',
    '/dianshiju/20740/player-1-13.html',
    '/dianshiju/20740/player-1-14.html',
    '/dianshiju/20740/player-1-15.html',
    '/dianshiju/20740/player-1-16.html',
    '/dianshiju/20740/player-1-17.html',
    '/dianshiju/20740/player-1-18.html',
    '/dianshiju/20740/player-1-19.html',
    '/dianshiju/20740/player-1-20.html',
    '/dianshiju/20740/player-1-21.html',
    '/dianshiju/20740/player-1-22.html']
    
    len1 = len(url_pool)
    
    def get_json_url(soup):
        url = soup.find("div",id = "iFrame_play").script.get('src')
        return location + url 
    
    def get_first_url(json_url):
        r2 = requests.get(json_url,headers = headers,timeout = 10).text
        dic = json.loads(r2[r2.find('{'):r2.find('}')+1])
        return dic['url']
    
    def get_real_m3u8_url(url):
        index_of_last = url.rfind('/')
        the_forward = url[:index_of_last]
        return the_forward + mid
    
    def get_the_ts_pack(url):
        r3 = requests.get(url,headers = headers,timeout = 10).text
        list_of_ts = r3.split('#')
        return list_of_ts
    
    def get_each_ts_url(the_ts_pack,the_real_m38u_url):
        len2 = len(the_ts_pack)
        for i in range(0,len2):
            suffix = the_ts_pack[i].split('
    ')[1]
            the_ts_pack[i] = the_real_m38u_url + "/" + suffix 
        # return the_ts_pack
    def mission(url,n,group):
        print('*****')
        response=requests.get(url,headers=headers,timeout = 10)
        print('-----')
        f=open("./"+str(group)+"/%03d.ts"%n,"wb")  
        f.write(response.content)      
        f.close()
        print("%03d.ts OK..."%n)
    
    def download(the_ts_pack,group):
        len3 = len(the_ts_pack)
        count = 0
        i = -1
        while i != len3-1:
            try:
                i+=1
                mission(the_ts_pack[i],i,group)
            except (requests.exceptions.ConnectionError,requests.exceptions.ReadTimeout):
                count+=1
                print(""+str(count)+"次等待")
                time.sleep(5)
                i-=1
            else:
                count=0
            time.sleep(0.5)
    # for i in range(0,len1):
    for i in range(12,22):
        completed_link = location + url_pool[i]
        r1 = requests.get(completed_link,headers=headers,timeout = 10)
        soup = BeautifulSoup(r1.text,"lxml")
        json_url = get_json_url(soup)
        time.sleep(0.1)
        the_first_mu38_url = get_first_url(json_url)
        time.sleep(0.1)
        the_real_m38u_url = get_real_m3u8_url(the_first_mu38_url)
        the_ts_pack = get_the_ts_pack(the_real_m38u_url + last)[5:-1]
        get_each_ts_url(the_ts_pack,the_real_m38u_url)
        print(the_ts_pack)
        download(the_ts_pack,i)
        print("" + str(i) + "组ts视频已经下载完成")
        time.sleep(10)
    
    
    
        #
    
    #
    # list1 = str1.rfind('/')
    # str2 = str1[:list1]
    # print(str2)
    
    
    
    # for i in range()
    
    # for each in url_pool:
    #     print(each)
    
    #
    
    
    
    
    
    # for n in range(1,167):
    #     mission(link + str(8000+n)+".ts",n)
    # dic = {'%3A':':','%2F':"/"}
    # str1 = str1.replace('%3A',':')
    # str1 = str1.replace('%2F','/')
    # print(str1)
    
    #
    # 
    # r = requests.get(link,headers = headers,timeout = 10)
    # text = r.text
    # print(text)
    
    # 

    注:因为视频有版权,网站地址就不放出来了,重要的是思路,每个网站都不一样,都要重新分析

    侵删!

    关于python异常机制:

    1.try-except代码块,就是如果有异常就执行except里的代码,然后如果有循环就跳过这一次(显然不符合要求,因为要下齐资源,所以要用到2)

    2.try-except-else代码块,如果有异常,就执行except内代码,如果没有,执行完try中代码后,继续执行else中代码

    另:except后跟的异常,可以是一个也可以是多个(多个使用“(..,..,..)”这种格式,不知道啥异常可以直接用Exception)

    因为代码执行过程中,服务器有的时候会返回不了信息,就要异常来处理,不然每次都手动怎么称得上自动化呢~

    希望对大家有所帮助

    以上

  • 相关阅读:
    Python爬虫连载1-urllib.request和chardet包使用方式
    Java连载69-接受输入、用数组模拟栈
    HTML连载61-焦点图、固定定位
    Java连载68-数组的拷贝、二维数组
    [Java] MVC
    [Java] JSP
    [Java] HTTP
    [设计模式] 设计模式课程(八)--抽象工厂模式
    [设计模式] 设计模式课程(七)--工厂模式
    [刷题] 75 Sort Colors
  • 原文地址:https://www.cnblogs.com/lavender-pansy/p/12198998.html
Copyright © 2011-2022 走看看