Python爬取高品质QQ音乐(2)

Python爬取高品质QQ音乐(2)

另一篇文章已经介绍了付费音乐的下载过程:传送门
这一篇主要是说一下爬取不同品质的QQ音乐(默认最高品质)。
知识点
1. 通过分析比较URL,判断不同品质音乐附带的参数。
2. 通过使用协程来判断url是否存在。
3. 使用pyquery来抓取歌曲的名字。

1、获取歌曲的名字

使用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]     # 歌曲的名字

2、获取加密的vkey

具体的步骤第一篇久介绍了,这里久直接贴上代码了。

    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']  # 加密的参数

3、获取不同音乐品质的URL

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)

4、通过协程来判断url的有效性

第一次使用协程,有可能理解的不正确,但是当前可以正常使用,明天来写一篇协程的知识点吧。

    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]    # 默认下载最高品质

5、音乐的下载

    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)

6、目前没解决的问题

  1. 就是用代码下载下来的qq音乐文件,在QQ音乐软件里面识别有问题,只能识别出来歌曲的名字。
  2. 通过url在Chrome下载的音乐都可以识别出来。
  3. 本来想添加批量下载喜欢的歌曲,目前只有分析获取的数据来获取喜欢的歌曲,还是要在登陆的前提,感觉没有意义(其实是做不出来)。

7、贴上总代码

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()

猜你喜欢

转载自blog.csdn.net/qq_1290259791/article/details/81159591