python 爬虫 双城之战 m3u8下载

在阅读文章前,可以去了解下ts视频,m3u8是什么,不然可能会影响阅读

英雄联盟的双城之战最近很火,尝试着在第三方视频网站下下载双层之战

目标url
url=https://www.315kc.com/dongman/yingxionglianmengshuangchengzhizhan1/2-1.html

进入网页简单分析一下,打开开发者工具,目的在于获取m3u8资源的来源:于是在快速搜索中搜索m3u8:在这里插入图片描述
在js中匹配到一个url网址,这里我们可以先复制下来去网页看一看:

https:\/\/new.iskcd.com\/20211107\/16gRmf0E\/index.m3u8

进入以后发现下载了个文件,用文本浏览器打开该文件
在这里插入图片描述
发现第三行是一个不完整的url
再根据网页请求来看(我的理解是先进行第一次的请求,获取真正的m3u8的地址,再请求真正的m3u8文件的地址,这也是为什么没带“1400kb”的请求会比带了"1400kb”参数请求的要快)
在这里插入图片描述
在这里插入图片描述
可以尝试用这不完整的url与获取到的url拼接替换一下 得到新的url:

https://new.iskcd.com/20211107/16gRmf0E/1400kb/hls/index.m3u8

访问该url后发现也是下载一个文件,打开该文件可以发现这就是我们要的ts文件的地址,而且这个地址没有加密,也不是只有部分连接,之后只要对每个链接发起请求就可以了。
在这里插入图片描述

整理下思路,我们的逻辑应该是这样的:

  1. 首先对视频链接发起请求,通过正则的方式匹配在js代码段的第一个m3u8的网址,得到第一个m3u8的文件
  2. .解析第一个m3u8文件,构造网址,在对获得的m3u8网址发起请求,得到第二个m3u8的网址并下载第二个m3u8文件
  3. 通过多线程对第二个m3u8文件中的链接分别发起请求并下载全部的ts文件。
  4. 通过命令将多个ts文件合并成一个ts文件,并且转换格式。(百度方法有很多 这里暂不涉及)

代码如下

import requests
import re
import os
import shutil
from urllib import parse
from lxml import etree
import json
import queue
import chardet
from requests.api import get, request
from random import sample
import codecs
import time
import threading

class HTMLdown(object):
    
    def downurl(self,url):
        if url is None:
            print('url错误')
            return None
        while 1:
            # proxies=proxiesPool.get_proxies()
            heads={
                "User-Agent":sample(user_agent_list,1)[0]
            }
            try:
                r=requests.get(url=url,headers=heads,timeout=5)
                # proxies=proxies,
                if r.status_code==200 :
                    # r.encoding='utf-8'
                    # r.encoding=chardet.detect(r.content)['encoding']
                    return r
                    
    
            except BaseException:
                print('url访问失败')
                time.sleep(5)
      
class HTMLparses(object):
    def get_first_m3u8_url(self,r):
        gz=re.compile(r'"url":"(.*?)",',re.S)
        first_m3u8_url=gz.search(r)
        first_m3u8_url =first_m3u8_url.group(1)
        return first_m3u8_url

    def get_second_m3u8_url(self,first_m3u8_url):
        with open('1.txt','r',encoding='utf-8') as f:
            line_list=f.readlines()
            for line in line_list:
                if '#' in line:
                    continue
        url_list=parse.urlparse(url=first_m3u8_url)
        url_parmas = (url_list.scheme, url_list.netloc, '', '', '', '')
        result = parse.urlunparse(url_parmas)
        second_m3u8_url=parse.urljoin(result,line[:-1])
        return second_m3u8_url

def down_ts(url_q):
    global nums,num
    while 1:
        try:
            url=url_q.get_nowait()
        except BaseException:
            break
        re=requests.get(url)
        with open('m3u8/'+num%nums,'wb') as ff:
                ff.write(re.content)
                nums+=1
        print(num%nums+'下载完成')


first_url='https://www.315kc.com/dongman/yingxionglianmengshuangchengzhizhan1/2-1.html'
down=HTMLdown()
parses=HTMLparses()
r=down.downurl(first_url).text

first_m3u8_url=parses.get_first_m3u8_url(r).replace('\\','')
# 得到第一个m3u8文件的地址
print(first_m3u8_url)

r=down.downurl(first_m3u8_url).content
with open('1.txt','wb') as f:
    f.write(r)

second_m3u8_url=parses.get_second_m3u8_url(first_m3u8_url)
print(second_m3u8_url)

r=down.downurl(second_m3u8_url).content
with open('2.txt','wb') as f:
    f.write(r)
# 下载最终的m3u8文件

path=r'2.txt'
num='%04d.ts'
nums=0
url_q=queue.Queue()
threads_list=[]
with open(path,'r') as f:
    rb_list=f.readlines()
    for rb in rb_list:
        if '#' in rb:
            continue
        url_q.put(rb)
threadNum=5#设置线程数量
start_time=time.time()
for i in range(threadNum):
   t= threading.Thread(target=down_ts,args=(url_q,))
   threads_list.append(t)
for t in threads_list:
    t.start()
for t in threads_list:
    t.join()
end_time=time.time()
print('下载完成 花费%s' % (end_time-start_time))
            

如果想要获取全集双城之战全集,只要分析出它每一集的网页构成,再完善m3u8文件的拼接,然后通过for循环就可以实现全集资源的获取了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值