初学python 很多高级的东西都还不知道,多以代码很臃肿
其实下视频最简单的方法就是用手机浏览器,像夸克啊之类的,自带的播放器打开视频播放网站,然后点击浏览器提供的下载功能,他其实也是通过解析网站的m3u8下载
但是问题在于公司的无线网把我们的外网都墙了,流量又限速,又是个影迷,就想着用电脑下好视频,传到手机上看。走起
* 通过我长时间的观察,一般视频网站,m3u8链接都是放在播放器的script中,所以使用 BeautifulSoup 在页面源代码中获取到包含 .m3u8 的script并提取出链接即可
content = requests.get(htmlUrl,headers=headers).text bsObj = BeautifulSoup(content,"html.parser") index = 0 for scriptItem in bsObj.findAll("script"): index += 1 if '.m3u8' in str(scriptItem): m3u8Start = str(scriptItem).find("\"url\":\"")+7 m3u8End = str(scriptItem).find(".m3u8")+5 m3u8Url = str(scriptItem)[m3u8Start:m3u8End].replace('\\','') global m3u8Url_before m3u8Url_before="https://" + m3u8Url.split('/')[2] #获取到m3u8文件,并保存m3u8的域名,防止ts链接为相对路径时,进行拼接
* 这里拿到的m3u8可能时最终的链接也可能时源链接,区别在于,最终链接里是包含 /hls/ 的,所以需要判断拿到的m3u8是否包含hls
# 链接是源链接时,需要加载出带有“hls”的链接
if 'hls' not in m3u8Url:
content = requests.get(m3u8Url,headers=headers).text
count = 0
nList = [] #存储出现换行位置的数组,用于后面取后两个换行位置之间的为m3u8链接
for item in list(content):
count += 1
if item == '\n':
nList.append(count)
m3u8Url_hls = str(content)[nList[-2]:nList[-1]]
# 判断此m3u8链接是否为绝对路径
if 'http' not in m3u8Url_hls:
m3u8Url_hls = m3u8Url_before + m3u8Url_hls
else:
m3u8Url_before = ''
else:
if index == len(list(bsObj.findAll("script"))):
print("在页面Script中未找到相关m3u8链接。。。")
* 拿到m3u8链接后,开始获取所有的ts链接,并存储到本地的txt文件中,后期判断,如果有这个文件,就跳过以上两步
def tsList(): #存储ts链接到本地txt文件
with open('E:/python/xxx/' + name + '.txt','r') as f:
if '.ts' in f.read():
print('ts视频链接均已存储,无需重复请求')
else:
print('开始获取并存储ts链接')
with open('E:/python/xxx/' + name + '.txt','r') as f:
m3u8Url = f.readlines()[0].strip()
# requests得到m3u8文件内容
content = requests.get(m3u8Url,headers=headers)
print(content.text)
#获取ts视频的加密链接,如果有的话,请求该链接,获取解密key并存储到相同txt中
jiami=re.findall('#EXT-X-KEY:(.*)\n',content.text)
if len(jiami)>0:
key=str(re.findall('URI="(.*)"',jiami[0]))[2:-2]
if 'http' not in key:
m3u8Start = m3u8Url.find("\"url\":\"")+7
m3u8End = m3u8Url.find(".m3u8")+5
m3u8Url = m3u8Url[m3u8Start:m3u8End].replace('\\','')
m3u8Url_before="https://" + m3u8Url.split('/')[2]
else:
m3u8Url_before = ''
keycontent= requests.get(m3u8Url_before + key,headers).text
with open('E:/python/xxx/' + name + '.txt','a') as f:
f.write(keycontent + '\n')
else:
#如果没有加密的话,直接使用00000000000进行占位,用于下载时的判断
with open('E:/python/xxx/' + name + '.txt','a') as f:
f.write('000000000000')
#开始请求m3u8链接,并通过链接的正则匹配出所有的ts文件链接
if(content.status_code == 200):
pattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+') # 匹配每一个ts链接
content = content.text.split(",")
index = 0
for item in content:
index += 1
url = str(pattern.findall(item))[2:-2]
with open('E:/python/xxx/' + name + '.txt','a') as f:
f.write(url + '\n')
Download()
* 以上,前期准备已完成,顺利的话,xxx.txt长这样

未完待续
