1. 程式人生 > >Python破解網易雲音樂下載版權限制

Python破解網易雲音樂下載版權限制

在播放某個音樂時,網易雲音樂會通過使用其api來解析這首音樂的id。
用Eminem的Rap God來舉例。

Rap God by Eminem

https://music.163.com/#/song?id=27853227
#注意其中顯示此音樂的id為27853227

網易雲用於解析id的api

https://music.163.com/song/media/outer/url?id=[id號]
Rap God: https://music.163.com/song/media/outer/url?id=27853227

訪問這個連結,會直接跳轉到這首歌的下載地址

https://m10.music.126.net/20181222125620/84340481235d7563b80a0536ecb6adb6/ymusic/2057/c470/618a/511a158c95fa942e8eeb0c6171684652.mp3
#注:由於這個站點會檢查Referer,直接訪問這個連結是沒有用的,要通過上面的api來訪問

根據我的多次實踐,絕大多數的瀏覽器並不會直接下載這個音樂檔案,而是直接在瀏覽器中播放,並且是沒有下載選項的。
但是由於暴露出了檔案位置,我們可以使用爬蟲來下載此音樂。大致思路是先訪問api,從返回的頭資訊中獲取要跳轉的Location,然後利用urllib.urlretrieve()來下載音樂檔案。


定義headers

headers = { 'User-agent':
            'Mozilla/5.0 (X11; Linux x86_64; rv:57.0)Gecko/20100101 Firefox/57.0',
            'Host':'music.163.com'
, 'Referer':'https://music.163.com'}

訪問api

import requests
ID = '27853227'
url = 'https://music.163.com/song/media/outer/url?id='
req = requests.get(url+ID, headers=headers, allow_redirects=False)

注意,如果不加headers,會返回狀態碼200並伴隨警告資訊

>>> req = requests.get('https://music.163.com/song/media/outer/url?id=27853227'
) >>> req <Response [200]> >>> req.text u'{"code":-460,"msg":"Cheating"}'

還有,如果不加allow_redirects=False,會直接報錯。這是由於requests庫是預設禁止302跳轉的

>>> req = requests.get('https://music.163.com/song/media/outer/url?id=27853227',headers=headers)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 67, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 53, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 597, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 195, in resolve_redirects
    **adapter_kwargs
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 576, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 426, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",))

獲取連結並使用urllib下載

import urllib
musicLink = req.headers['Location']
urllib.urlretrieve(musicLink, 'music/rapgod.mp3') 

完整程式碼

import urllib, requests
headers = { 'User-agent':
            'Mozilla/5.0 (X11; Linux x86_64; rv:57.0)Gecko/20100101 Firefox/57.0',
            'Host':'music.163.com',
            'Referer':'https://music.163.com'}

ID = '27853227'
url = 'https://music.163.com/song/media/outer/url?id='
req = requests.get(url+ID, headers=headers, allow_redirects=False)
musicLink = req.headers['Location']

urllib.urlretrieve(musicLink,"music/rapgod.mp3")

新手小白第一次發文,非喜誤噴