Python爬蟲實戰,DecryptLogin模塊,Python模擬登錄實現網易雲個人歌單下載器


前言

今天來寫個網易雲音樂個人歌單下載器唄,讓我們愉快地開始吧~

開發工具

** Python版本:**3.6.4

** 相關模塊:**

DecryptLogin模塊;

argparse模塊;

prettytable模塊;

click模塊;

以及一些python自帶的模塊。

環境搭建

安裝Python並添加到環境變量,pip安裝需要的相關模塊即可。

DecryptLogin安裝方式參見(因為經常更新,已經安裝過的小伙伴麻煩記得更新一下,否則可能會在新的案例中報錯)

原理簡介

既然是模擬登錄系列,首先自然是先模擬登錄網易雲音樂啦,這個利用我們開源的DecrpytLogin庫可以輕松地實現:

'''利用DecryptLogin實現模擬登錄'''
@staticmethod
def login(username, password):
  lg = login.Login()
  infos_return, session = lg.music163(username, password)
  return infos_return.get('userid'), session

接着就是獲取登錄用戶創建/收藏的歌單列表(注意,因為只是一個小例子,所以僅支持下載登錄用戶自己創建/收藏的歌單,當然這代碼應該很容易可以擴展到下載任意歌單T_T),通過抓包分析(其實網上很多地方可以找到別人分析完后公開的網易雲音樂api,需要的可以去知乎或者Github之類的網站上搜索一下對應關鍵字)我們可以發現登錄用戶所有歌單的列表可以通過請求以下API獲取:

https://music.163.com/weapi/user/playlist?csrf_token=

其中csrf_token的值在用戶登錄后的session的cookies中可以找到,由此我們可以獲得我們需要的歌單相關的信息,代碼實現如下:

'''獲得所有歌單'''
def getPlayLists(self):
  playlist_url = 'https://music.163.com/weapi/user/playlist?csrf_token='
  playlists = []
  offset = 0
  while True:
    data = {
          "offset": offset,
          "uid": self.userid,
          "limit": 50,
          "csrf_token": self.csrf
        }
    res = self.session.post(playlist_url+self.csrf, headers=self.headers, data=self.cracker.get(data))
    playlists += res.json()['playlist']
    offset += 1
    if not res.json()['more'] == 'false':
      break
  all_playlists = {}
  for item in playlists:
    name = item.get('name')
    track_count = item.get('trackCount')
    play_count = item.get('playCount')
    play_id = item.get('id')
    if item.get('creator').get('userId') == self.userid:
      attr = '我創建的歌單'
    else:
      attr = '我收藏的歌單'
    all_playlists[str(play_id)] = [name, track_count, play_count, attr]
  return all_playlists

接着,用戶將選擇想要下載的歌單id,根據歌單id,我們將利用以下api來獲得該歌單的詳細信息:

https://music.163.com/weapi/v6/playlist/detail?csrf_token=

具體而言,代碼實現如下:

def getPlayListSongs(self, playlist_id, num_songs):
  detail_url = 'https://music.163.com/weapi/v6/playlist/detail?csrf_token='
  offset = 0
  song_infos = {}
  while True:
    data = {
          'id': playlist_id,
          'offset': offset,
          'total': True,
          'limit': 1000,
          'n': 1000,
          'csrf_token': self.csrf
        }
    res = self.session.post(detail_url+self.csrf, headers=self.headers, data=self.cracker.get(data))
    tracks = res.json()['playlist']['tracks']
    for track in tracks:
      name = track.get('name')
      songid = track.get('id')
      artists = ','.join([i.get('name') for i in track.get('ar')])
      brs = [track.get('h')] + [track.get('m')] + [track.get('l')]
      song_infos[songid] = [name, artists, brs]
    offset += 1
    if len(list(song_infos.keys())) >= num_songs:
      break
  return song_infos

其中返回的信息中br(其實就是歌曲比特率)和歌曲id在后續的歌曲下載中是必須要的,其他信息的提取主要是為了用戶交互的需要。接着,當用戶確定是下載該歌單中的所有歌曲時,程序就開始下載所有歌曲啦。而某首歌曲下載的代碼在之前的音樂下載器里分享過,copy過來稍微改下大概就是這個這樣了:

'''下載某首歌曲'''
def downloadSong(self, songid, songname, brs, savepath='.'):
  play_url = 'http://music.163.com/weapi/song/enhance/player/url?csrf_token='
  print('正在下載 ——> %s' % songname)
  for br in brs:
    data = {
          'ids': [songid],
          'br': br.get('br'),
          'csrf_token': self.csrf
        }
    res = self.session.post(play_url+self.csrf, headers=self.headers, data=self.cracker.get(data))
    if res.json()['code'] == 200:
      download_url = res.json()['data'][0].get('url', '')
      if download_url:
        break
  with closing(self.session.get(download_url, headers=self.headers, stream=True, verify=False)) as res:
    total_size = int(res.headers['content-length'])
    if res.status_code == 200:
      label = '[FileSize]:%0.2f MB' % (total_size/(1024*1024))
      with click.progressbar(length=total_size, label=label) as progressbar:
        with open(os.path.join(savepath, songname+'.'+download_url.split('.')[-1]), "wb") as f:
          for chunk in res.iter_content(chunk_size=1024):
            if chunk:
              f.write(chunk)
              progressbar.update(1024)

文章到這里就結束了,感謝你的觀看,關注我每天分享Python模擬登錄系列,下篇文章分享網抑雲個人聽歌排行榜爬取


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM