手把手教你爬取某酷音乐付费歌曲~

2021-08-05 15:39:21 浏览数 (1)

爬取酷我音乐相比网易云音乐、酷狗音乐以及QQ音乐来说容易很多,没有加密算法,而且在反爬虫中不存在一些难理解的逻辑,只需要理清思路即可!本文会用爬虫 GUI制作酷我音乐下载工具

GUI编写思路

本文的爬虫程序是根据下面的GUI界面进行封装的,GUI创建是使用PySimpleGUI库:

所以GUI制作思路是这样的:

  • 通过搜索框搜索歌曲名称或者歌手,取得歌曲的名称等信息,通过信息展示框进行展示以及传入歌曲选择框中。
  • 在歌曲选择框中输入歌曲信息或者选择要保存的歌曲,然后点击Button按钮保存。
  • 点击保存按钮会出现一个弹框,可以选择音频数据保存的路径。
  • Button按钮退出程序直接结束工具的运行。

根据设计图以及思路得到下面代码:

代码语言:javascript复制
# 主题设置
sg.theme('BrownBlue')  # BrownBlue  LightBrown3

# 布局设置 类似网页前端代码
layout = [ # 搜索框布局  Text:文本  Combo:输入框 tooltip:鼠标移动到输入框显示的内容 size:输入框宽度 Button:按钮 key:唯一标识
     [sg.Text('请输入搜索的歌曲或歌手:', font=("微软雅黑", 12)),
           sg.Combo(values='', tooltip='请输入搜索的歌曲或歌手:', font=("微软雅黑", 10), default_value='', auto_size_text=True,
                    size=(70, 0), key='keys'), sg.Button('搜索', font=("微软雅黑", 12))],
    # 歌曲选择框布局
          [sg.Text('请选择或输入要保存的歌:', font=("微软雅黑", 12)),
           sg.Combo(values='', tooltip='请选择或输入要保存的歌:', font=("微软雅黑", 10), default_value='', auto_size_text=True,
                    size=(70, 0), key='value'), sg.Button('保存', font=("微软雅黑", 12))],
    # 信息展示框  Output:输出元素 
          [sg.Text('信息展示:', justification='center')],
          [sg.Output(size=(100, 10), font=("微软雅黑", 10))],
    # 退出程序按钮
          [sg.Text('', font=("微软雅黑", 12), size=(73, 1)),sg.Button('退出程序', font=("微软雅黑", 12))]
          ]
# 创建窗口
window = sg.Window('酷我音乐下载器', layout, font=("微软雅黑", 12), default_element_size=(80, 1))

# 事件循环 类似网页后端代码
while True:
    event, values = window.read()
    # 点击退出程序按时结束事件循环
    if event in (None, '退出程序'): 
        break

window.close()

GUI布局完成,后面只需要编写爬虫以及在事件循环中增加相关后端代码即可!

爬虫编写思路

根据GUI结构,我们需要一个搜索功能,这里直接在酷我音乐首页搜索框搜索音乐抓包,拿到搜索框搜索内容的ap:i

得到url:

代码语言:javascript复制
http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=毛不易&pn=1&rn=30&httpsStatus=1&reqId=705d4d00-cd07-11eb-bb69-59cd8661b1da

其中key是搜索的内容,pn是页码,rn是数据的条数,reqId没看出来,但不要紧,不影响操作。url的参数基本了解了,其中修改key值即可获取不同歌曲数据,最终得到data_text()函数。

代码语言:javascript复制
def data_text(key):
    global headers # 后面需要用到,设置为全局变量
    keys = urllib.parse.quote(key) # 把得到的key转化为电脑看得懂的符号
    headers = {
        'Cookie': '你的cookie',
        'csrf': 'GVDHKPAN1HS',
        'Host': 'www.kuwo.cn',
        'Referer': f'http://www.kuwo.cn/search/list?key={keys}',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36'
    }
    url_rid = f'http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key={keys}&pn=1&rn=30&httpsStatus=1&reqId=8468f010-a011-11eb-9364-1b542cb8c9e7Request Method'
    return url_rid

虽然得到了该url,但我们还不知要从url中提取哪些内容;所以我们需要进入下一页面,继续抓包,找到上一条url和下一条url的关联性。

随便点击任意一首歌曲,当然,付费歌曲是无法在网页上播放的,但酷我音乐的付费内容和免费内容都是用一条链接的,所以播放免费歌曲进入播放页:

在播放页抓包,成功找到包含MP3格式的数据包,得到url:

代码语言:javascript复制
http://www.kuwo.cn/url?format=mp3&rid=28501751&response=url&type=convert_url3&br=128kmp3&from=web&t=1623690057540&httpsStatus=1&reqId=168e5e60-cd32-11eb-ba7a-a1bfcaa82f84

经过测试,只需要url中的参数rid发生变化即可获取不同的歌曲,最后获得MP3url_rid()MP3_URL()函数:

代码语言:javascript复制
def MP3url_rid(url_rid):
    data = []
    rid_response = requests.get(url_rid, headers=headers).json()
    lists = rid_response['data']['list']
    for i in lists:
        time.sleep(2)
        name = i['name']  # 歌名
        artist = i['artist']  # 歌手
        rid = i['rid']  # id值
        data.append([name, artist, rid])
        print(name, artist, rid, sep=' | ')
    # 传入到歌曲选择框选择
    window["value"].Update(values=data, font=("微软雅黑", 10), size=(15, 8))

def MP3_URL(file_s, name, artist, rid):
    url_mp3 = f'http://www.kuwo.cn/url?format=mp3&rid={rid}&response=url&type=convert_url3&br=128kmp3&from=web&t=1618728266452&httpsStatus=1&reqId=849a8760-a011-11eb-9364-1b542cb8c9e7'
    url_response = requests.get(url=url_mp3, headers=headers).json()
    mp3_url = url_response['url']
    mp3_name = name   '_'   artist   '.mp3'
    print(mp3_name)
    # 传入保存函数进行保存
    save(file_s, mp3_name, mp3_url)

条件循环

在事件循环中加入点击搜索按钮和保存按钮所触发的事件:

代码语言:javascript复制
if event == '搜索':
    if values['keys']:
     # 接收搜索框内容
        key = values['keys']
        # 传入函数
        url_rid = data_text(key)
        MP3url_rid(url_rid)
        print('搜索完成, 请选择要下载的歌曲!')
        # 弹窗
        sg.popup('搜索完成, 请选择要下载的歌曲!')
    else:
        print('歌曲或歌手未输入!')
        sg.popup('歌曲或歌手未输入!')

if event == '保存':
    if values['value']:
     # sg.popup_get_folder() 弹窗的一种,接收的是文件路径
        files = sg.popup_get_folder('请选择存储路径:')
        # 接收MP3url_rid()函数内容
        mp3data = values['value']
        q = mp3data[0]
        w = mp3data[1]
        e = mp3data[2]
        MP3_URL(files, q, w, e)
        print('下载完成!')
        sg.popup('下载完成!')
    else:
        print('未选择或者输入歌曲!')
        sg.popup('未选择或者输入歌曲!')

运行示例,最后可以用pyinstaller进行程序代码打包:

0 人点赞