vergica

  写这篇随笔时,代码已经写完好久了,最近一直在琢磨如何用pyinstaller打包,正好最近开始用博客园,现在才决定写一写(大佬不喜勿喷)

  这有个前身版本,我写在CSDN上了,可以去看看,是关于api分析的(只是最后学校开学就断更了,不知道以后有没有机会补上)

  好,现在可以进入正题了(●\'◡\'●)写了点注释供小白参考

  下载酷我音乐:

def kuwo(tempath):
    songid = re.findall(r\'.*?play_detail/(\d*)\', songurl)[0]
    audiolink = json.loads(
        requests.get(f\'http://m.kuwo.cn/newh5app/api/mobile/v1/music/src/{songid}\').text)[\'data\'][\'url\']
    audio = requests.get(audiolink, timeout=10).content
    # 获取信息
    res = requests.get(f\'https://m.kuwo.cn/newh5/singles/songinfoandlrc?musicId={songid}\').text
    text = json.loads(res)[\'data\'][\'songinfo\']
    name = text[\'songName\']
    artists = text[\'artist\'].replace(\'&\', \'\')
    album = text[\'album\']
    lyric = \'\'
    for i in json.loads(res)[\'data\'][\'lrclist\']:
        lyric += \'[{}:{}.{}]\'.format(\'%02d\' % math.floor(float(i[\'time\']) / 60),
                                     \'%02d\' % math.floor(float(i[\'time\']) % 60),
                                     (\'%.2f\' % math.modf(float(i[\'time\']))[0])[2:])
        lyric += i[\'lineLyric\'] + \'\n\'
    # 保存文件
    filename = re.sub(r"[\\/:*?\"<>|]", "", artists) + \' - \' + re.sub(r"[\\/:*?\"<>|]", "", name)
    with open(path + filename + \'.aac\', \'wb\') as f1:
        f1.write(audio)
        f1.close()
    if len(lyric) != 0:
        with open(path + filename + \'.lrc\', \'w\', encoding="UTF-8") as f2:
            f2.write(lyric)
            f2.close()
    strcmd = fr\'"{tempath}\ffmpeg\bin\ffmpeg.exe" -i "{path + filename}.aac" -acodec libmp3lame "{path + filename}.mp3"\'
    subprocess.call(strcmd, creationflags=0x08000000)
    os.remove(path + filename + \'.aac\')
    file = ID3(path + filename + \'.mp3\')
    file[\'TIT2\'] = TIT2(encoding=3, text=name)
    file[\'TPE1\'] = TPE1(encoding=3, text=artists)
    file[\'TALB\'] = TALB(encoding=3, text=album)
    file.save()
    return f\'《{name}》下载完成!\'

  这当中要注意的是酷我音乐下下来的歌曲文件是aac格式,我调用了ffmpeg把格式转换成了mp3,然后才能调用mutagen库写入歌曲信息,所以运行时要确保ffmpeg在tempath下哦(没有ffmpeg的小朋友请戳这里,当然也可以自己去官网找最新版)。

  下载网易云音乐(无法试听的歌下不了):

def wangyi():
    songid = re.findall(r\'.*?id=(\d*)\', songurl)[0]
    audiolink = requests.get(f\'http://music.163.com/song/media/outer/url?id={songid}.mp3\',
                             headers={\'user-agent\': \'\'}).url
    if audiolink != \'https://music.163.com/404\':
        audio = requests.get(audiolink).content
        # 获取信息
        res = requests.get(f\'https://music.163.com/api/song/detail/?ids=%5B{songid}%5D\').text
        text = json.loads(res)[\'songs\'][0]
        name = text[\'name\']
        album = text[\'album\'][\'name\']
        artists = []
        for artist in text[\'artists\']:
            artists.append(artist[\'name\'])
        artists = \'\'.join(artists)
        lyric = \'\'
        lrctext = json.loads(requests.get(f\'https://music.163.com/api/song/lyric?id={songid}&lv=1&tv=-1\').text)
        if \'nolyric\' not in lrctext:
            lrc = lrctext[\'lrc\'][\'lyric\']
            tlrc = lrctext[\'tlyric\'][\'lyric\'] + \'\n\'
            for m in re.compile(r\'(\[\d*:\d*.\d*])(.*?)\n\').findall(lrc + \'\n\'):
                lyric += m[0] + m[1] + \' \'
                for n in re.compile(r\'(\[\d*:\d*.\d*])(.*?)\n\').findall(tlrc + \'\n\'):
                    if n[0] == m[0] and n[1] != m[1]:
                        lyric += n[1]
                lyric += \'\n\'
        # 保存文件
        filename = re.sub(r"[\\/:*?\"<>|]", "", artists) + \' - \' + re.sub(r"[\\/:*?\"<>|]", "", name)
        with open(path + filename + \'.mp3\', \'wb\') as f1:
            f1.write(audio)
            f1.close()
        if len(lyric) != 0:
            with open(path + filename + \'.lrc\', \'w\', encoding="UTF-8") as f2:
                f2.write(lyric)
                f2.close()
        file = ID3(path + filename + \'.mp3\')
        file[\'TIT2\'] = TIT2(encoding=3, text=name)
        file[\'TPE1\'] = TPE1(encoding=3, text=artists)
        file[\'TALB\'] = TALB(encoding=3, text=album)
        file.save()
        return f\'《{name}》下载完成!\'
    else:
        return f\'暂不支持下载\'

  这里我干了一件有意思的事情,就是在处理歌词这一部分,如果有更好的匹配方法,欢迎留言哦。

  最后整理整理,完整代码差不多像这样:

main.py

import requests
import re
import json
from mutagen.id3 import ID3, TIT2, TPE1, TALB
import getpass
import math
import subprocess
import os
import shutil
import sys


def kuwo(tempath):
    ...


def wangyi():
    ...


if __name__ == \'__main__\':
    path = r\'C:/Users/{}/Music/\'.format(getpass.getuser())
    tpath = getattr(sys, \'_MEIPASS\', os.path.dirname(os.path.abspath(__file__)))
    print(\'欢迎使用...\')
    songurl = input(\'请输入:\n\')
    while songurl != \'exit\':
        if \'music.163.com\' in songurl:
            print(wangyi())
        elif \'kuwo.cn\' in songurl:
            print(kuwo(tpath))
        songurl = input(\'请输入:\n\')
    shutil.rmtree(tpath)
    print(\'感谢使用(* ̄▽ ̄*)\')

  顺带提一嘴如何使用pyinstaller打包软件,首先生成spec:

pyi-makespec -F -i {ico路径} -n {项目名} main.py

  -F是打包成单文件的意思(默认多文件),如果省略-n,第一个脚本的主文件名将作为spec的名字。

  然后找到生成的spec(我的在用户文件夹下)修改如下:

...
datas=[(\'C:\\Users...\\ffmpeg\', \'ffmpeg\')]
...

  第一个是资源文件夹的位置,第二个是生成临时目录的名称。如果和我不一样的注意上面的python代码不能照搬!

  最后生成exe:

pyinstaller -F {文件名.spec}

 

分类:

技术点:

相关文章: