• 爬某音乐平台的付费音乐 Python 被标题党搞烦了的可以来看看


    疫情在家是真的无聊,最近发现有人分享了个某我vip音乐的接口。前面做爬虫的时候一直只能爬到免费音乐,今天来爬爬付费音乐。当然,免费的也可以这样爬。申明:本文仅做学习交流使用,如有侵权,请联系我删除。

    爬虫思路:

    • 搜索歌曲或者歌手;
    • 分析搜索结果页,有json找json,没json找网页渲染的列表;然后通过parsel等分析歌曲列表信息;
    • 点击一首歌曲,通过开发者工具分析,查找歌曲请求的地方;
    • 撸码实现过程;
    • 保存歌曲;
    • 用excel文档或者csv进行保存歌曲有关的文字信息(方便后续做可视化)

    第一段代码,用函数写的:

      1 import os.path
      2 import time
      3 from urllib.parse import quote
      4 import openpyxl
      5 import requests
      6 import concurrent.futures
      7 
      8 def get_response(page_url):
      9     headers = {
     10         "Cookie": "_xxx",
     11         "csrf": "x",
     12         # "Host": "www.xwo.cn",
     13         "Referer": "http://www.xwo.cn/",
     14         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36",
     15     }
     16     response = requests.get(url=page_url, headers=headers)
     17     response.raise_for_status()
     18     response.encoding = response.apparent_encoding
     19     response.encoding = 'utf-8'
     20     return response
     21 
     22 def save_media(musicRealUrl, musicName, artist, wusun):
     23     # 保存音频
     24     # 首先创建文件
     25     filePath = f'./{singer}/'
     26     if not os.path.exists(filePath):
     27         os.mkdir(filePath)
     28     # 开始请求音乐的真实地址
     29     musicContent = get_response(musicRealUrl).content
     30     with open(filePath + musicName + ' - ' + artist + ' - ' + wusun + '.mp3', mode='wb') as f:
     31         f.write(musicContent)
     32         print(f'正在下载------------------------------->{musicName},请稍等!')
     33 
     34 def main(singer, numPage):
     35     # 创建一个文档进行保存文字信息
     36     wb = openpyxl.Workbook()
     37     ws = wb.create_sheet(title=f'{singer}', index=0)
     38     wb.remove(wb['Sheet'])
     39     # 创建表头
     40     sheetHeader = ['歌曲名','歌曲id','歌手','歌手id','专辑','专辑id','是否无损',
     41                    '是否收费','是否有mv','时长','评分','发行日期']
     42     ws.append(sheetHeader)
     43     # 解析音乐列表页面
     44     for page in range(1, int(numPage)):
     45         print(f"------------------------开始请求第{page}页数据,请稍等。--------------------------------------")
     46         url = f'http://www.xxx.cn/api/www/search/searchMusicBykeyWord?key={quote(singer)}&pn={page}&rn=30&httpsStatus=1&reqId=a2dd3070-b252-11ec-a25f-e554156f3f5e'
     47         url = f'http://www.xxx.cn/api/www/search/searchMusicBykeyWord?key={quote(singer)}&pn={page}&rn=30&httpsStatus=1&reqId=59ec28e1-b25b-11ec-9f5c-69be3534bacd'
     48         print(url)
     49         # exit()
     50         json_data = get_response(url).json()
     51         song_list = json_data['data']['list'] # 歌曲列表
     52         for item in song_list:
     53             # 开始解析歌曲列表
     54             musicName = item['name'] # 歌曲名称
     55             musicId = item['rid'] # 歌曲
     56             artist = item['artist'] # 歌手
     57             aristId = item['artistid']  # 歌手编号
     58             album = item['album'] # 歌曲所属专辑
     59             if album:
     60                 album = item['album']
     61             else:
     62                 album = None
     63 
     64             albumid = item['albumid']  # 专辑ID
     65             if albumid:
     66                 albumid = item['albumid']
     67             else:
     68                 albumid = None
     69 
     70             lossLess = item['hasLossless'] # 是否无损
     71             if lossLess:
     72                 lossLess = '无损'
     73             else:
     74                 lossLess = ''
     75 
     76             listenFee = item['isListenFee'] # 是否收费
     77             if listenFee:
     78                 listenFee = ''
     79             else:
     80                 listenFee = ''
     81 
     82             hasMv = item['hasmv'] # 是否有mv
     83             if hasMv:
     84                 hasMv = ''
     85             else:
     86                 hasMv = '没有'
     87             songTime = item['songTimeMinutes'] # 歌曲时长
     88             songScore = item['score100'] # 歌曲评分
     89             releaseDate = item['releaseDate'] # 歌曲发行时间
     90             if releaseDate == "1970-01-01":
     91                 releaseDate = '未知'
     92             else:
     93                 releaseDate = item['releaseDate']
     94             ws.append([musicName, musicId, artist, artist, album, albumid, lossLess,
     95                        listenFee, hasMv, songTime, songScore, releaseDate])
     96             # 开始拼接url
     97             musicRequestUrl = 'https://xxx.kuwo.cn/anti.s?response=url&rid=MUSIC_' + str(musicId) + '&format=acc|mp3&type=convert_url'
     98             # print(musicRequestUrl)
     99             musicRealUrl = get_response(musicRequestUrl).text
    100             print(musicRealUrl)
    101             # 开始请求真实地址
    102             save_media(musicRealUrl=musicRealUrl, musicName=musicName, artist=artist, wusun=lossLess)
    103     wb.close()
    104     wb.save(f'./{singer}//{singer} - {time.strftime("%Y-%m-%d", time.localtime())}.xlsx') # 按歌手名和当前日期进行保存
    105 
    106 if __name__ == "__main__":
    107     singer = input('你想要下载的歌手:')
    108     numPage = input('你想要下载前几页的歌曲(一页30条):')
    109     url = f'http://www.kuwo.cn/search/list?key={quote(singer)}'
    110     main(singer, numPage)

    第二段代码是把上面的函数整理成了类方法,用面向对象方法写的:

      1 import time
      2 import openpyxl
      3 import requests
      4 import os
      5 from urllib.parse import quote
      6 
      7 class kuwoSpider():
      8     headers = {
      9         "Cookie": "xx8x",
     10         "csrf": "xx", # 统称为令牌
     11         # "Host": "www.kuwo.cn", # 这里的host在下载页面的时候不需要,不然会403
     12         "Referer": "http://www.kxxo.cn/",
     13         "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.82 Safari/537.36",
     14     }
     15 
     16     def __init__(self, singer, numPage, headers=headers):
     17         self.singer = singer
     18         self.numPage = numPage
     19         self.headers = headers
     20 
     21     def get_response(self, url):
     22         response = requests.get(url=url, headers=self.headers)
     23         response.raise_for_status()
     24         response.encoding = response.apparent_encoding
     25         response.encoding = 'utf-8'
     26         return response
     27 
     28     def save_media(self, musicRealUrl, musicName, artist, wusun):
     29         # 保存歌曲
     30         filePath = f'./{self.singer}/' # ./表示在当前目录下创建一个文件
     31         if not os.path.exists(filePath):
     32             os.mkdir(filePath)
     33 
     34         # 尝试解析音乐的二进制数据
     35         musicContent = self.get_response(url=musicRealUrl).content
     36         # 开始保存
     37         with open(filePath + musicName + ' - ' + artist + ' - ' + wusun + '.acc', mode='wb') as f:
     38             f.write(musicContent)
     39             print(f'正在下载------------->{musicName},请稍等!')
     40 
     41     def parse_search_page(self,):
     42         # 创建excel文档
     43         wb = openpyxl.Workbook() # 创建工作簿
     44         ws = wb.create_sheet(title=f'{self.singer} - {time.strftime("%Y-%m-%d", time.localtime())}', index=0) # 创建表
     45         ws.append(['歌曲名','歌曲id','歌手','歌手id','专辑','专辑id','是否无损',
     46                    '是否收费','是否有mv','时长','评分','发行日期']) # 添加表头
     47         wb.remove(wb['Sheet'])
     48         # 解析搜索页,解析歌曲并保存歌曲的信息
     49         for page in range(1, self.numPage):
     50             url = f'http://www.xxx.cn/api/www/search/searchMusicBykeyWord?key={quote(self.singer)}&pn={page}&rn=30&httpsStatus=1&reqId=59ec28e1-b25b-11ec-9f5c-69be3534bacd'
     51             # 开始解析歌曲页面
     52             json_data = self.get_response(url=url).json()
     53             # 歌曲列表
     54             song_lists = json_data['data']['list']
     55             # print(song_lists)
     56             # 提取每首歌的歌曲信息
     57             for item in song_lists:
     58                 # 开始解析歌曲列表
     59                 musicName = item['name']  # 歌曲名称
     60                 musicId = item['rid']  # 歌曲
     61                 artist = item['artist']  # 歌手
     62                 aristId = item['artistid']  # 歌手编号
     63                 album = item['album']  # 歌曲所属专辑
     64                 if album:
     65                     album = item['album']
     66                 else:
     67                     album = None
     68 
     69                 albumid = item['albumid']  # 专辑ID
     70                 if albumid:
     71                     albumid = item['albumid']
     72                 else:
     73                     albumid = None
     74 
     75                 lossLess = item['hasLossless']  # 是否无损
     76                 if lossLess:
     77                     lossLess = '无损'
     78                 else:
     79                     lossLess = ''
     80 
     81                 listenFee = item['isListenFee']  # 是否收费
     82                 if listenFee:
     83                     listenFee = ''
     84                 else:
     85                     listenFee = ''
     86 
     87                 hasMv = item['hasmv']  # 是否有mv
     88                 if hasMv:
     89                     hasMv = ''
     90                 else:
     91                     hasMv = '没有'
     92                 songTime = item['songTimeMinutes']  # 歌曲时长
     93                 songScore = item['score100']  # 歌曲评分
     94                 releaseDate = item['releaseDate']  # 歌曲发行时间
     95                 if releaseDate == "1970-01-01":
     96                     releaseDate = '未知'
     97                 else:
     98                     releaseDate = item['releaseDate']
     99                 #  开始保存文本信息到excel
    100                 ws.append([musicName, musicId, artist, artist, album, albumid, lossLess,
    101                        listenFee, hasMv, songTime, songScore, releaseDate])
    102                 # 拼接歌曲播放的请求url
    103                 musicRequestUrl = 'https://xxx.kuwo.cn/anti.s?response=url&rid=MUSIC_' + str(musicId) + '&format=acc|mp3&type=convert_url'
    104                 # 请求url并获取到下载地址
    105                 musicRealUrl = requests.get(url=musicRequestUrl).text # 这里的headers不一样
    106                 # 开始调用函数进行保存
    107                 self.save_media(musicRealUrl=musicRealUrl, musicName=musicName, artist=artist, wusun=lossLess)
    108 
    109         wb.close() # 关闭表格
    110         wb.save(f'./{self.singer}//{self.singer} - {time.strftime("%Y-%m-%d", time.localtime())}.xlsx') # 保存到当前歌手目录下
    111 
    112 
    113     def run(self):
    114         # 最后执行的函数
    115         self.parse_search_page()
    116 
    117 if __name__ == "__main__":
    118     # 程序入口,传入歌手或者歌曲名还有要采集的页数
    119     singer = input("请输入歌手或者歌曲:")
    120     numPage = int(input("请输入要采集的最大页数(每页30条):")) # 强制转换,不然运行程序的时候会出现str和int类型的问题
    121     app = kuwoSpider(singer, numPage)
    122     app.run()

    程序运行截图:

    几个问题:

    • headers参数,根据开发者工具添加的时候最好按顺序,比如,cookies,user-agent,不要user-agent,cookies,不然会网页会无响应,程序获取不到数据;
    • 请求歌曲真实播放地址的时候,就是.mp3后缀的地址的时候,headers里的host参数,要剔除,不然会无响应,403,程序获取不到数据;
    • 保存excel文件的时候,我这里写的都是变量,要注意f和/还有{,一不小心就出错了;
    • 定页码的时候,可以定成一页一页爬取,每次爬完运行程序,我这里是批量爬取;

    为防止面向监狱编程,代码里有关headers参数和url参数地方都有改动。很多人爬付费音乐的时候卡在播放真实地址的那个地方,他的程序都只能获取到免费音乐,遇到付费的就提示类似的:‘该为付费音乐’怎么地,那是因为在没有会员的前提下,我们所能抓取的东西,就只能那么多。有心人可以百度那个播放请求的地址,也可以自己充个会员,然后通过开发者工具抓取播放请求的地址,还有一种方法,就是留言留邮箱,我发给你。

    最后:不要相信那种标题党类似 -- 白嫖,用python爬取付费音乐。这种人只会哗众取宠,为了点流量和博人眼球,浪费查找资料人的时间和感情,用阳寿在写代码,祝他们早点下18层。

  • 相关阅读:
    第四次作业
    第三次作业
    第二次作业。
    国庆作业。
    实验2-4
    实验2-3
    实验2-2
    实验2-1
    实验1-3
    实验 1-1
  • 原文地址:https://www.cnblogs.com/mafu/p/16096246.html
Copyright © 2020-2023  润新知