另一篇文章已经介绍了付费音乐的下载过程:传送门
这一篇主要是说一下爬取不同品质的QQ音乐(默认最高品质)。
知识点
1. 通过分析比较URL,判断不同品质音乐附带的参数。
2. 通过使用协程来判断url是否存在。
3. 使用pyquery来抓取歌曲的名字。
使用pyquery来获取title。
def get_name(self): # 获取歌曲的名字
response = requests.get(url=self.music_url).text
doc = pq(response)
self.music_name = doc('title').text().split('-')[0] # 歌曲的名字
具体的步骤第一篇久介绍了,这里久直接贴上代码了。
def get_params(self): # 获取加密的vkey
self.params = self.music_url[self.music_url.rindex(
'/') + 1:self.music_url.rindex('.')] # 获取音乐的ID
params_url = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?&jsonpCallback=MusicJsonCallback&cid=205361747&songmid=' + \
self.params + '&filename=C400' + self.params + '.m4a&guid=9082027038' # 加密参数的url
response = requests.get(params_url, verify=False) # 访问加密的网址
response = json.loads(response.text)
self.vkey = response['data']['items'][0]['vkey'] # 加密的参数
music_type = {
'C400': 'm4a',
'M500': 'mp3',
'M800': 'mpe',
'A000': 'ape',
'F000': 'flac'
} # m4a, mp3普通, mp3高, ape, flac
上面的参数是通过分析比较下载地址,来获取的不同品质的参数。接下来就是将上面的参数拼接到url。
def get_quality(self): # 获取不同品质的url
# quality_id = input('请输入1-5(默认最高)')
index_music_url = 'http://dl.stream.qqmusic.qq.com/{}' + self.params + \
'.{}?vkey=' + self.vkey + '&guid=9082027038&uin=0&fromtag=53'
music_type = {
'C400': 'm4a',
'M500': 'mp3',
'M800': 'mpe',
'A000': 'ape',
'F000': 'flac'
} # m4a, mp3普通, mp3高, ape, flac
music_urls = [] # 下载音乐的地址
for k, v in music_type.items():
music_url = index_music_url.format(k, v)
music_urls.append(music_url)
self.get_url(music_urls)
第一次使用协程,有可能理解的不正确,但是当前可以正常使用,明天来写一篇协程的知识点吧。
def get_url(self, music_urls): # 用协程判断是否存在不同音乐品质的url
result = []
async def get(url):
session = aiohttp.ClientSession()
response = await session.get(url)
status_code = response.status
# session.close()
return status_code
async def request(url):
response = await get(url)
if response == 200:
result.append(url)
tasks = [asyncio.ensure_future(request(url)) for url in music_urls]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
self.music_download_url = result[-1] # 默认下载最高品质
def download_music(self): # 音乐的下载
response = requests.get(url=self.music_download_url,stream=True)
with open(self.music_name+'.mp3', 'wb') as f:
for check in response.iter_content(1024):
f.write(check)
import requests
import json
import asyncio
import aiohttp
from pyquery import PyQuery as pq
class YinYue:
def __init__(self, url):
self.music_url = url # 音乐的url
self.music_id = None # 音乐的ID
self.music_download_url = None # 最终音乐的下载地址
self.music_name = None #音乐的名字
self.vkey = None # 加密的参数
self.params = None # 提交的参数
def get_name(self): # 获取歌曲的名字
response = requests.get(url=self.music_url).text
doc = pq(response)
self.music_name = doc('title').text().split('-')[0] # 歌曲的名字
def get_params(self): # 获取加密的vkey
self.params = self.music_url[self.music_url.rindex(
'/') + 1:self.music_url.rindex('.')] # 获取音乐的ID
params_url = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?&jsonpCallback=MusicJsonCallback&cid=205361747&songmid=' + \
self.params + '&filename=C400' + self.params + '.m4a&guid=9082027038' # 加密参数的url
response = requests.get(params_url, verify=False) # 访问加密的网址
response = json.loads(response.text)
self.vkey = response['data']['items'][0]['vkey'] # 加密的参数
def get_quality(self): # 获取不同品质的url
# quality_id = input('请输入1-5(默认最高)')
index_music_url = 'http://dl.stream.qqmusic.qq.com/{}' + self.params + \
'.{}?vkey=' + self.vkey + '&guid=9082027038&uin=0&fromtag=53'
music_type = {
'C400': 'm4a',
'M500': 'mp3',
'M800': 'mpe',
'A000': 'ape',
'F000': 'flac'
} # m4a, mp3普通, mp3高, ape, flac
music_urls = [] # 下载音乐的地址
for k, v in music_type.items():
music_url = index_music_url.format(k, v)
music_urls.append(music_url)
self.get_url(music_urls)
def get_url(self, music_urls): # 用协程判断是否存在不同音乐品质的url
result = []
async def get(url):
session = aiohttp.ClientSession()
response = await session.get(url)
status_code = response.status
# session.close()
return status_code
async def request(url):
response = await get(url)
if response == 200:
result.append(url)
tasks = [asyncio.ensure_future(request(url)) for url in music_urls]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
self.music_download_url = result[-1] # 默认下载最高品质
def download_music(self): # 音乐的下载
response = requests.get(url=self.music_download_url,stream=True)
with open(self.music_name+'.mp3', 'wb') as f:
for check in response.iter_content(1024):
f.write(check)
yinyue = YinYue('https://y.qq.com/n/yqq/song/000KHhaJ4S0hOL.html')
yinyue.get_name()
yinyue.get_params()
yinyue.get_quality()
yinyue.download_music()