热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mu3u8系列(一)练手spider

本次目标http:www.qiqi.lavod-detail-id-46194.html目的,down魔道祖师,实现前期分析文件得到以下粗略步骤1进入二级页面,
本次目标  http://www.qiqi.la/vod-detail-id-46194.html
    目的,down魔道祖师,实现
    前期分析文件得到以下粗略步骤
1 进入二级页面,找到  

    得到网址
2 访问      https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf
    需要带上协议头
    Referer: https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf
    User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36    
    返回另一个页面response_1
    得到文件标题 
3 在response_1
    得到:var main = "/20180710/4671_a5ef5a19/index.m3u8?sign=b0023d8b455da27a4294b38c7815f7b3";
    拼合网页:https://cn2.zuixinbo.com/20180710/4671_a5ef5a19/index.m3u8?sign=b0023d8b455da27a4294b38c7815f7b3
    访问:得到返回结果
        #EXTM3U
        #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=800000,RESOLUTION=1080x608
        1000k/hls/index.m3u8
4 拼合 https://cn2.zuixinbo.com/20180710/4671_a5ef5a19/1000k/hls/index.m3u8
    带协议访问
        Referer: https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf
        User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
    得到.ts下载文件路径
    分段下载
5 拼合.ts文件

有空更新完整代码
 2018-10-21
    开始编写代码 

     发现在重新写代码的过程中,发现直接在播放页面就有全部的播放地址,只不过是用usc2的
        编码转换了一下,我们需要把其转换成ansi编码
    2 OK,这下直接拿到播放地址,做一下格式化的工作,进行第2步解析,上面的第一步工作算是白费了一片心思

    3 按照上面步骤依次完成,基本没问题

    

# -*- coding:utf-8 -*-
# @time:2018-10-21 14:43
# @Auther:1043453579@qq.com

from urllib.request import Request
from urllib.request import urlopen
import re,time,os
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor

static_url_1 = 'http://www.qiqi.la/vod-detail-id-46194.html'
class A(object):
    def __init__(self,url,e=15):
        self.header= {'user-agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}
        self.path = os.getcwd()
        self.e = e
        self.static_url='https://cn2.zuixinbo.com'

    def num_of_e(self,url_2):#进入二级页面
        res = urlopen(Request(url=url_2,headers=self.header)).read()
        res = res.decode()

        title = self.take_middle_text(res,'') #标题
        var_main=re.search('var main = "(.*?)";',res).group(1) #访问下级地址
        if not var_main:
            exit()
        return {'var_main':var_main,'referer':url_2,'标题':title}


    def open_3(self,url,referer='',**kwargs):
        url=self.static_url+url
        a={'Referer': referer}
        a.update(self.header)
        res = urlopen(Request(url=url,headers=a)).read()
        res = res.decode()
        _=self.take_middle_text(res,'1080x608','.m3u8')+'.m3u8' #得到ts视频地址
        return {'url':_.split(),'regerer1':url}


    def open_4(self,url,referer1='',**kwargs):
        referer=referer1
        referer= referer.split('/')
        referer=referer[0:-1]
        referer.append(*url)
        url='/'.join(referer)
        print(url)
        a = {'Referer': referer1}
        a.update(self.header)
        res = urlopen(Request(url=url,headers=a)).read()
        res = res.decode()
        ts_list=[]
        for i in res.split('\n'):
            try:
                if i[0]!='#':
                    ts_list.append(i)
            except:pass
        return {'ts_list':ts_list,'url':url}

    def take_middle_text(self,txt, txt_s, txt_e='', seeks=0, seeke=0):
        # 取出中间文本,真返回中间文本,假返回False
        # seeks有传参,会按照取前几位取值
        # seeke有传参,会按照取后几位取值
        try:
            if txt_e or seeks or seeke:
                pass
            else:
                raise 1
            s_1 = txt.find(txt_s)
            if s_1 == -1:
                raise 1
            l_1 = len(txt_s)
            if txt_e:
                s_2 = txt.find(txt_e)
                if s_1 == -1 or s_2 == -1:
                    return False
                return txt[s_1 + l_1:s_2]
            if seeks:
                return txt[s_1 - seeks:s_1]
            if seeke:
                return txt[s_1 + l_1:s_1 + l_1 + seeke]
        except:
            return '传参错误或未找到传参文本'

    def down_ts(self,dict,path_1):
        url = os.path.dirname(dict['url'])+'/'
        ts_list=dict['ts_list']
        for i in ts_list:
            print(path_1,'这里是path_1')
            path = os.path.join(path_1, i)
            print(path,'这里是path_ts文件网址')
            if os.path.exists(path):
                print('已存在,跳过')
            else:
                try:
                    res = urlopen(Request(url=url+i,headers=self.header)).read()
                    with open(path,'wb') as f:
                        f.write(res)
                    print('成功写入一条')
                except:
                    print('写入失败')

    def main(self,url):
        dict_1 = self.num_of_e(url) #'这里返回一个字典 '
        dict_2 = self.open_3(dict_1['var_main'],dict_1['referer'])
        dict_3 = self.open_4(dict_2['url'], dict_2['regerer1']) #这里的url未提纯
        title = dict_1['标题']
        path = os.path.join(self.path,title)
        #@print(title,'这里是标题')
        if not os.path.exists(path):
            os.mkdir(path) #没有就创建一个新的目录
        self.down_ts(dict_3,path)


if __name__ == '__main__':

    ex = ProcessPoolExecutor(2)
    a_1 = A(static_url_1, 15)
    with open('2.txt', 'r', encoding='utf8') as f:
        for i in f:
            a = i.split()[0].split('$')[1].split('#')[0]
            print(ex.submit(a_1.main,a).result())
        ex.shutdown()
View Code---第一版,用双进程当作并发,代理未加,隔几天再优化一下,先这样吧

 

2018-10-30

# -*- coding:utf-8 -*-
# @time:2018-10-21 14:43
# @Auther:1043453579@qq.com

from urllib.request import Request
from urllib.request import urlopen
import re,time,os
from concurrent.futures import ProcessPoolExecutor,ThreadPoolExecutor

static_url_1 = 'http://www.qiqi.la/vod-detail-id-46194.html'
class A(object):
    def __init__(self):
        self.header= {'user-agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36'}
        self.path = os.getcwd()
        #self.static_url='https://cn2.zuixinbo.com'
        self.static_url = ''
        #self.r = redis.Redis(host='127.0.0.1',port=6379,db=0)

    def get_proxy(self):
        return {'http':self.r.randomkey().deocode()}

    def down_1(self,url,referer='',code=True):
        while True:
            #proxy = self.get_proxy()
            #这里设置代理
            try:
                _ = self.header
                if referer:
                    a = {'Referer': referer}
                    _.update(a)
                res = urlopen(Request(url=url, headers=_),timeout=60).read()
                if code:
                    res = res.decode()
                if res:
                    time.sleep(1)
                    return res
                else:
                    raise 1
            except Exception as e:
                print('请求失败',url)
                with open('3.txt','a+') as f:
                    f.write(url)
                    f.write('\n')
                time.sleep(10)
                

    def num_of_e(self,url_2):#进入二级页面
        res = self.down_1(url_2)
        title = self.take_middle_text(res,'') #标题
        var_main=re.search('var main = "(.*?)";',res).group(1) #访问下级地址
        if not var_main:
            exit()
        return {'var_main':var_main,'referer':url_2,'标题':title}


    def open_3(self,url,referer='',**kwargs):
        url=self.static_url+url
        res = self.down_1(url,referer=referer)
        _=self.take_middle_text(res,'1080x608','.m3u8')+'.m3u8' #得到ts视频地址
        return {'url':_.split(),'regerer1':url}


    def open_4(self,url,referer1='',**kwargs):
        referer=referer1
        referer= referer.split('/')
        referer=referer[0:-1]
        referer.append(*url)
        url='/'.join(referer)
        print(url)
        res = self.down_1(url,referer=referer1)
        ts_list=[]
        for i in res.split('\n'):
            try:
                if i[0]!='#':
                    ts_list.append(i)
            except:pass
        return {'ts_list':ts_list,'url':url}

    def take_middle_text(self,txt, txt_s, txt_e='', seeks=0, seeke=0):
        # 取出中间文本,真返回中间文本,假返回False
        # seeks有传参,会按照取前几位取值
        # seeke有传参,会按照取后几位取值
        try:
            if txt_e or seeks or seeke:
                pass
            else:
                raise 1
            s_1 = txt.find(txt_s)
            if s_1 == -1:
                raise 1
            l_1 = len(txt_s)
            if txt_e:
                s_2 = txt.find(txt_e)
                if s_1 == -1 or s_2 == -1:
                    return False
                return txt[s_1 + l_1:s_2]
            if seeks:
                return txt[s_1 - seeks:s_1]
            if seeke:
                return txt[s_1 + l_1:s_1 + l_1 + seeke]
        except:
            return '传参错误或未找到传参文本'

    def down_ts(self,dict,path_1):
        url = os.path.dirname(dict['url'])+'/'
        ts_list=dict['ts_list']
        for i in ts_list:
            path = os.path.join(path_1, i)
            if os.path.exists(path):
                print('已存在,跳过',i)
            else:
                try:
                    res = urlopen(Request(url=url+i,headers=self.header),timeout=60).read()
                    time.sleep(1)
                    if res:
                        with open(path,'wb') as f:
                            f.write(res)
                        print('成功写入一条',i)
                    else:
                        raise 1
                except Exception as e:
                    with open('3.txt','a+') as f:
                        _ = '-'.join([str(i) for i in time.localtime()[0:6]])
                        f.write(_ +'###'+e+'$$$'+url)
                        f.write('\n')
                        print('写入失败',i,e)
        time.sleep(5)

    def main(self,url):
        _ = url.split('com')
        self.static_url=_[0]+'com'
        dict_1 = self.num_of_e(url) #'这里返回一个字典 '
        dict_2 = self.open_3(dict_1['var_main'],dict_1['referer'])
        dict_3 = self.open_4(dict_2['url'], dict_2['regerer1']) #这里的url未提纯
        title = dict_1['标题']
        path = os.path.join(self.path,title)
        #@print(title,'这里是标题')
        if not os.path.exists(path):
            os.mkdir(path) #没有就创建一个新的目录
        self.down_ts(dict_3,path)

if __name__ == '__main__':
    ex = ProcessPoolExecutor(3)
    a_1 = A()
    with open('2.txt', 'r', encoding='utf8') as f:
        for i in f:
            a = i.split()[0].split('$')[1].split('#')[0]
            ex.submit(a_1.main,a)
        ex.shutdown()

#BUG在网页的提交网址中
View Code--代理未加,需要的请自行加上代理,稍微优化了一下,里面的2.txt是下载地址,见下面
第01集$https://cn2.zuixinbo.com/share/722caafb4825ef5d8670710fa29087cf#
第02集$https://cn2.zuixinbo.com/share/fbad540b2f3b5638a9be9aa6a4d8e450#
第03集$https://v-xunlei.com/share/c457d7ae48d08a6b84bc0b1b9bd7d474#
第04集$https://v-xunlei.com/share/8db1d4a631a6e9a24e2c0e842e1f1772#
第05集$https://v-xunlei.com/share/197f76fe309657064dbec74d9eea4be4#
第06集$https://v-xunlei.com/share/92b70a527191ca64ca2df1cc32142646#
第07集$https://v-xunlei.com/share/abc99d6b9938aa86d1f30f8ee0fd169f#
第08集$https://v-xunlei.com/share/22cdb13a83f73ccd1f79ffaf607b0621#
第09集$https://v-xunlei.com/share/aceacd5df18526f1d96ee1b9714e95eb#
第10集$https://v-6-cn.com/share/075b051ec3d22dac7b33f788da631fd4#
第11集$https://v-6-cn.com/share/4670c07872d5314c6ad6ffa633d4a059#
第12集$https://v-xunlei.com/share/2bba9f4124283edd644799e0cecd45ca#
第13集$https://v-cntv-cn.com/share/d87aa42cd08ba8612664a73dbdb64221#
第14集$https://v-cntv-cn.com/share/63ceea56ae1563b4477506246829b386#
第15集$https://v-cntv-cn.com/share/e8a69bf65aefc23d0f360ab695e9eac7
View Code--这里是下载地址

 

 


推荐阅读
  • Scrapy 爬取图片
    1.创建Scrapy项目scrapystartprojectCrawlMeiziTuscrapygenspiderMeiziTuSpiderhttps:movie.douban.c ... [详细]
  • 文章目录简介HTTP请求过程HTTP状态码含义HTTP头部信息Cookie状态管理HTTP请求方式简介HTTP协议(超文本传输协议)是用于从WWW服务 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • 本文整理了常用的CSS属性及用法,包括背景属性、边框属性、尺寸属性、可伸缩框属性、字体属性和文本属性等,方便开发者查阅和使用。 ... [详细]
  • 最近在学Python,看了不少资料、视频,对爬虫比较感兴趣,爬过了网页文字、图片、视频。文字就不说了直接从网页上去根据标签分离出来就好了。图片和视频则需要在获取到相应的链接之后取做下载。以下是图片和视 ... [详细]
  • 目录爬虫06scrapy框架1.scrapy概述安装2.基本使用3.全栈数据的爬取4.五大核心组件对象5.适当提升scrapy爬取数据的效率6.请求传参爬虫06scrapy框架1. ... [详细]
  • 博主使用代理IP来自于网上免费提供高匿IP的这个网站用到的库frombs4importBeautifulSoupimportrandomimporturllib.re ... [详细]
  • 延迟注入工具(python)的SQL脚本
    本文介绍了一个延迟注入工具(python)的SQL脚本,包括使用urllib2、time、socket、threading、requests等模块实现延迟注入的方法。该工具可以通过构造特定的URL来进行注入测试,并通过延迟时间来判断注入是否成功。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • python+selenium十:基于原生selenium的二次封装fromseleniumimportwebdriverfromselenium.webdriv ... [详细]
  • css,背景,位置,y,background, ... [详细]
author-avatar
shanfeng0828_589
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有