音悦Tai,创立于2009年,是一家专注于高清MV在线欣赏与传播的音乐分享平台。跟紧新歌发片速度,通过筛选网友提供的内容,第一时间为用户呈现MV作品。音悦Tai还是广大的MV爱好者的社交网络平台,在音悦Tai建设“我的家”,把自己的最爱MV、悦单秀给大家,以找到志趣相投的悦友。
我们的目标是通过使用Python的requests库实现mv的下载,然后到本地播放!实现输入或复制音悦台当前播放的MV链接到程序中,即可实现MV的下载。 环境:python3.7 pycharm
第一步:打开音悦台的任何页面,然后快捷键按F12,可以出现开发者工具
这时候刷新下页面,可以看到下侧列表有很多资源
编辑
我们的思路是找到视频的播放链接地址,然后打开再写入本地文件,所以需要在里面找到有用的东西,通过认真寻找找到有个链接的返回有如下信息,可以点开Response,但是json格式,这里我们点开Preview预览可以看到如下相关的MV信息,里面有个videoUrl,这里就是我们要的播放链接:
编辑
第二步:通过requests库实现代码端的访问,然后将此链接的返回转成json格式,也就是python的反序列化数据,让其读入内存中
import requests
import json
url = 'https://www.yinyuetai.com/play?id=151'
mvid = url.split('=')[-1]
info_url = 'https://data.yinyuetai.com/video/getVideoInfo?id={}'.format(mvid)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Sa'
}
res = requests.get(info_url)
html = res.text
print(html)
mv_url = json.loads(html)['videoUrl']
mv_name = json.loads(html)['videoName']
print(mv_url)
print(mv_name)
返回结果如下:编辑
第三步:既然播放链接已经拿到了,现在是不是可以直接请求了,我试了如下:
response = requests.get(mv_url, headers=headers, stream=True)
print(response)
编辑
浏览器直接访问也是403,按理说这个链接是可以直接访问的,但是却报了403
编辑
经过查询资料发现这是网站做了反爬措施,增加了防盗链的设置,因此我们的请求头除了包含浏览器的参数外,还需要包含referer的请求头,这样网站就可以识别你的请求是从此网站内部跳转过来的。编辑
headers增加referer参数后如下:
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Sa'
, 'Referer': 'https://www.yinyuetai.com/'}
再次请求为200
编辑
第四步:既然请求正常后,现在就是要去打开视频播放链接,然后写入本地文件,这里的请求需要注意的是要加上stream=True参数
response = requests.get(mv_url, headers=headers, stream=True)
查阅资料相关解释如下:
编辑
第五步:就是把这个请求的返回二进制内容写入到本地文件,文件以mv的名字命名,这里代码略,请看最终代码。
因为是下载所以最好有进度条看起来方便,我写了两种进度条供大家选择,都可正常运行,如果你需要使用其中一种,请注意代码的注释,或者将其封装成方法去调用也可,最终代码如下:
# Author:Nebula
import json
import os
import sys
from contextlib import closing
import requests
from tqdm import tqdm
def download_mv(url):
mvid = url.split('=')[-1]
info_url = 'https://data.yinyuetai.com/video/getVideoInfo?id={}'.format(mvid)
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Sa'
, 'Referer': 'https://www.yinyuetai.com/'}
# 参考视频请求报403的原因 https://www.jianshu.com/p/d907f9f6bb2c 这里加上Referer
res = requests.get(info_url)
html = res.text
print(html)
mv_url = json.loads(html)['videoUrl']
mv_name = json.loads(html)['videoName']
# print(mv_url)
response = requests.get(mv_url, headers=headers, stream=True)
# # print(response.status_code)
# # print(response.headers['content-length'])
#
# 新建一个文件夹
if not os.path.exists('D:/音悦台mv'):
os.mkdir('D:/音悦台mv')
# 简易进度条 参考链接:https://www.cnblogs.com/zhuminghui/p/13985315.html
n = 1
content_size = int(response.headers['content-length'])
if response.status_code == 200:
with open('D:/音悦台mv/{}.mp4'.format(mv_name), "wb") as f:
for i in response.iter_content(chunk_size=1024):
rate = n * 1024 / content_size
print("\r", end="")
print("《{0}》大小:{1}MB 下载进度:{2:%}".format(mv_name,int(content_size/1024/1024),rate), "▋"*(n//2048), end="")
sys.stdout.flush()
f.write(i)
n += 1
print("下载完成")
# 带自更新进度的进度条 进度条参考链接:https://www.jb51.net/article/227211.htm
# with closing(requests.get(mv_url, stream=True)) as res:
# total_size = int(res.headers['content-length'])
# if res.status_code == 200:
# with open('D:/音悦台mv/{}.mp4'.format(mv_name), "wb") as f,tqdm(
# desc=mv_name, # 进度条的前面的提示
# total=total_size, # 迭代元素的多少
# unit='B', # 用来定义每个迭代单元的字符串。默认为"it",表示每个迭代;在下载或解压时,设为"B",代表每个“块”。
# unit_scale=True, # 如果设置为1或者True,迭代数量就会被自动减少或者重置,且将在国际单位制标准后面添加一个度量前缀(kilo、mega等)[默认:False]
# unit_divisor=1024, # float, optional:默认为1000
# ) as progressbar:
# for chunk in res.iter_content(chunk_size=1024):
# if chunk:
# f.write(chunk)
# progressbar.update(1024)
if __name__ == '__main__':
# url = input('Enter the mv url you want to download:')
url = 'https://www.yinyuetai.com/play?id=153'
download_mv(url)
最终效果如下:
(简易进度条)下载中:
编辑
(简易进度条)下载完成:
编辑
编辑
可以正常进行播放:
编辑