V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
sergiojune
V2EX  ›  Python

用 Python 代码来下载任意指定网易云歌曲

  •  4
     
  •   sergiojune · 2018-08-10 13:32:34 +08:00 · 5695 次点击
    这是一个创建于 2296 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前两天教了大家如何在控制台上找到真实的 mp3 播放地址,但是不可以下载付费的,因为只能下载可播放的歌曲。至于怎样下载付费网易云音乐,还是开个会员吧,要知道免费是最贵的的这个道理。

    有粉丝看了前两天文章想用代码来装逼,我就为了满足他,特意去折腾了两天,终于写出来了,迫不及待与大家分享一把。不得不说,这里面坑很大,遇到几个大坑在那里折腾了几个小时,分享出来让大家想装逼的少踩点坑。废话不多说,开始今天主题!

    1.寻找目标请求

    打开网易云主页 ,打开开发者工具,点击搜索

    是不是看到很多请求,不要慌,慢慢找。找了之后你会发现下面这个链接

    这个链接返回的是 json,里面包含的是歌曲的信息,但是没有 MP3 播放链接,这个或许有用,因为有歌曲的 id,先放着。

    我试着点击歌曲播放,又增加了几个请求。一看,里面就有我想要的 MP3 链接。

    这样子,获取 mp3 请求的链接出来了,https://music.163.com/weapi/song/enhance/player/url?csrf_token=

    可以看到是个 post 请求,状态码为 200,我们接着往下看 fromdata 是什么数据。

    是两个加密了的参数,不过不怕,如果你看过我之前写的利用 python 爬取网易云音乐,并把数据存入 mysql你会发现 fromdata 参数是一样的,所以破解加密参数思路是一样的,不过这次我不用 fiddler 了,只用开发者工具来调试,看好了!!!我们看看这个请求的来源是什么。

    点进去看看,是个混淆的 js,点左下角可以格式化,这样好看点。

    进行搜索params,你会发现这个:

    可以看到,加密的方式都没有改变,还是和之前一样,只是变量名字改变了。**window.asrsea()**有四个参数,先看看后面三个参数,因为都很相似。继续进行搜索定位。

    可以看出,返回的是一个固定的内容,所以不用管了,等下可以进行调试抓出来。再看看第一个参数。是一个 json。我们可以进行断点调试进行获取。

    进行刷新,你会看到下面这些内容。

    可以看到**window.asrsea()**是一个 d 函数,定位过去看看,然后又给个断点。

    点击去往下一个断点,你会看到

    四个参数都出来了,我直接贴出来这里吧:

    d:"{"ids":"[523946593]","br":128000,"csrf_token":""}"e:"010001"f:"00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"g:"0CoJUm6Qyw8W8jud"
    

    参数都出来了,很容易就知道 d 参数里面的 ids 对应的就是歌曲 id,所以说刚才找的链接有用了。br 是个固定值,对应的可能是歌曲的质量之类的,不需要管的。

    下面再看看 d 函数是如何加密的:

    里面又包含了很多 **a , b ,c **的三个函数,先看看 a 函数

    这个 a 函数是在一堆字符串中随机找出 16 个字符串。ok,下一个。

    b 函数采用了 aes 加密, 加密的密文是 e ,也就是参数的 a 内容,c是密钥,第三个参数中有偏移量 d 和加密模式 **CBC **。再看看 c 函数。

    c 函数是采用 rsa 加密,b 为加密指数, 空字符串为解密参数,c 为加密系数。

    好了,三个函数分析完毕,再回头看看 d 函数。

    可以看到 params 参数是经过两次 b 函数生成的,也就是用 aes 加密两次,encSecKey 参数是通过 c 函数生成的,也就是通过 rsa 加密方式生成的。

    废话不多说,Talk is cheap, show me the code

    2.代码部分

    先把随机生成 16 个字符串的展示下

    为了让大家好看点,代码以后都用照片代替

    接下来是 aes 加密的

    这里有一个巨坑,谷歌了也没发现有谁遇到过,就是用 python 进行 aes 加密的时候,只能加密数字和字母,不能对中文进行加密,会报错

    Input strings must be a multiple of 16 in length

    解决方方法是在cbc加密的模式下,在对字符串补齐为长度为 16 的倍数时,长度指标不能用中文,要先把他转为 unicode 编码的长度才可以。比如上面的,下面的就是错误示范

    pad = 16 - len(text) % 16

    此坑爬过去了,接着下一个 rsa 加密

    还有需要注意一下的是,在生成随机 16 个字符串的时候,需要保证 params 和 encSecKey 两个参数是对应的这个随机字符串是一致的。要不然加密之后还是会出错,获取不了正确信息。好了,最后一个是获取两个加密参数。

    代码写完了,那还等什么,运行一下装逼啊!

    {'code': -460, 'msg': 'Cheating'}

    这下好了,装逼失败,被网易云认出来我是爬虫的,那我试试加下请求头?结果加了还是一个样,这个也算是个巨坑吧。解决方法还是加请求头,只需要加两个,一个是浏览器识别 **user-agent **,另一个是 cookie ,想不到吧?我也想不到,居然还有在cookie上面做反爬的,但是我用了 **session **来保持 cookie 还是不行,需要自己复制浏览的 cookie 就行保存才可以。

    歌曲现在能下载了,可我要的是任意歌曲啊。那好,我们再去看看这个请求 https://music.163.com/weapi/cloudsearch/get/web?csrf_token=,因为返回的是歌曲 id。

    3.寻找歌曲 id

    可以看到,参数还是和上面的那个请求的参数一样,但是我们知道的是那个 d 函数,后三个参数是不变的,所以我们只需要找前面那个变化的参数就可以了,还是同样的操作,断点调试

    也是很容易就找到的,d 参数就是下面这个

    d = '{"hlpretag":"<span class=\"s-fc7\">","hlposttag":"","s":"可能否","type":"1","offset":"0","total":"true","limit":"30","csrf_token":""}'

    这个分析就可以说完毕了。

    4.搜索歌曲代码

    这个是获取歌曲 id 的代码,其他的没什么问题了。

    最后

    我还将程序打包了,遇到了喜欢的歌曲都可以下载下来,虽然可以直接用网易云下载,不用那么麻烦,但是我们学编程的是要干什么的?装逼啊,能用代码绝不用其他的东西。

    效果图如上,下载杠杆的,需要完整代码的可以后台回复音乐即可送给你。

    ps:原创不易,写了这篇文章可谓花费了我 1024 根头发,听说转发是生发的最有效之道,所以你懂得!

    扫面二维码关注获取更多有趣的 python 文章

    第 1 条附言  ·  2018-08-10 15:05:21 +08:00
    仅用于技术学习,不作任何商业用途。
    42 条回复    2018-08-14 11:02:03 +08:00
    mossss21
        1
    mossss21  
       2018-08-10 13:48:40 +08:00
    同志开下门,查下七月的水表!
    VVVVVEX
        2
    VVVVVEX  
       2018-08-10 13:54:59 +08:00
    同志开下门,有你快递!
    vegito2002
        3
    vegito2002  
       2018-08-10 13:58:37 +08:00
    同志开下门, 我是美团外卖!
    Mrkon
        4
    Mrkon  
       2018-08-10 13:58:44 +08:00
    律师函警告
    glacer
        5
    glacer  
       2018-08-10 14:13:09 +08:00
    这个加密函数也太容易被定位了,没啥意义啊
    Commencal
        6
    Commencal  
       2018-08-10 14:21:15 +08:00
    下载的是高音质的吗
    Baboonowen
        7
    Baboonowen  
       2018-08-10 14:33:26 +08:00 via Android
    网易的 api 和加密 GitHub 一堆分析
    InDown
        8
    InDown  
       2018-08-10 14:45:41 +08:00
    8 月加急名单!
    luoo3699
        9
    luoo3699  
       2018-08-10 14:48:11 +08:00
    chrome 声海盗插件了解下
    wl2358
        10
    wl2358  
       2018-08-10 14:52:23 +08:00 via Android
    律师函警告
    easylee
        11
    easylee  
       2018-08-10 14:55:03 +08:00 via Android
    能把思路写出了,非常感谢。

    不知道是不是我见识短浅,自从乌云到了之后这种性质或者之上的实战文章越来越少。
    onepi
        12
    onepi  
       2018-08-10 14:56:47 +08:00   ❤️ 1
    你再这样小心我叫小春和你聊聊
    sergiojune
        13
    sergiojune  
    OP
       2018-08-10 15:00:54 +08:00
    @onepi 这么恐怖的吗
    sergiojune
        14
    sergiojune  
    OP
       2018-08-10 15:01:34 +08:00
    我在考虑要不要删除了...被大家吓到了。
    vimiix
        15
    vimiix  
       2018-08-10 15:02:47 +08:00
    同志,记得把声明信息补上,仅用于技术学习云云
    L0star
        16
    L0star  
       2018-08-10 15:04:32 +08:00
    虽然不会 看着爽啊
    sergiojune
        17
    sergiojune  
    OP
       2018-08-10 15:04:45 +08:00
    @vimiix 多谢提醒,真的被吓到了,只是分享下知识。。
    cnmllll
        18
    cnmllll  
       2018-08-10 15:05:43 +08:00
    弱弱问下,付费音乐也能下载么
    sergiojune
        19
    sergiojune  
    OP
       2018-08-10 15:07:00 +08:00
    @cnmllll 不能的,还是付费下载吧。
    hansonwang99
        20
    hansonwang99  
       2018-08-10 15:43:39 +08:00
    点赞
    leon2013
        21
    leon2013  
       2018-08-10 16:35:43 +08:00
    点赞
    coolooks
        22
    coolooks  
       2018-08-10 16:45:36 +08:00
    为了省 8 块钱,真是费心了
    ae86
        23
    ae86  
       2018-08-10 16:48:58 +08:00
    干货,点赞👍
    hiccup00
        24
    hiccup00  
       2018-08-10 16:52:20 +08:00 via Android
    喜欢这种干货~
    bilibalao
        25
    bilibalao  
       2018-08-10 16:53:26 +08:00
    感觉可以写一个脚本 [滑稽]
    SharkU
        26
    SharkU  
       2018-08-10 18:52:57 +08:00
    [musicbox]( https://github.com/darknessomi/musicbox)
    尽管前人做过了,但是楼主写出了思路过程。
    lzuntalented
        27
    lzuntalented  
       2018-08-10 19:07:18 +08:00
    https://github.com/lzuntalented/music-fetch
    另一种获取播放地址的方式
    youngxu
        28
    youngxu  
       2018-08-10 19:16:15 +08:00 via Android
    是不是高音质的?
    如果不是高音质的,那和 F12 开发者工具里面的 Network-Elements 有什么区别…那个还简单
    sergiojune
        29
    sergiojune  
    OP
       2018-08-10 19:21:35 +08:00
    @youngxu 都说了只是技术交流,我又不是为了下载音乐才搞的,而且这个可以通过改参数来改音质吧
    wsly47
        30
    wsly47  
       2018-08-10 20:29:38 +08:00 via iPhone   ❤️ 2
    roshad
        31
    roshad  
       2018-08-10 20:32:08 +08:00
    教解密技术是挺好的,但是可以的话,解个别的吧,毕竟音乐人也不容易.
    sudri
        32
    sudri  
       2018-08-10 20:37:41 +08:00
    牛逼,挖个坑改日再填
    noword2say
        33
    noword2say  
       2018-08-10 20:42:21 +08:00 via Android
    偷偷自己用就好了啊😨发出来不就……
    sergiojune
        34
    sergiojune  
    OP
       2018-08-10 21:08:29 +08:00
    @roshad 这里没有破解 vip,只是下载个音乐而已。
    cy97cool
        35
    cy97cool  
       2018-08-11 00:05:29 +08:00
    问题来了 如果对每个网站都要这么分析一波 甚至人家上 WebAssembly 就更加复杂了
    有没有啥通用的自动化逆向代码生成爬取代码呢,如果使用 chrome-headless 效率太低
    sergiojune
        36
    sergiojune  
    OP
       2018-08-11 00:16:33 +08:00
    @cy97cool 兄弟想多了
    wangfei324017
        37
    wangfei324017  
       2018-08-11 11:46:31 +08:00 via iPhone
    nb,小心网易发来律师含哈哈哈
    tomfs
        38
    tomfs  
       2018-08-11 15:43:57 +08:00 via iPhone
    个人觉得,既然图片这么多了,何不做成视频更易阅读,干货点赞
    sergiojune
        39
    sergiojune  
    OP
       2018-08-11 16:46:27 +08:00
    @tomfs 出视频的话可能你就看不到了
    snal123
        40
    snal123  
       2018-08-12 13:16:49 +08:00
    楼主我按着你的教程,请求来源 js 那里,跳出来 n 个 js,随便点了一个,然后接着调试,然而发现调试的 d 参数没有歌曲的 id,感觉是点的 js 跟你不一样导致的。
    sergiojune
        41
    sergiojune  
    OP
       2018-08-12 14:11:56 +08:00
    @snal123 首先要找对 js 文件,然后因为网易云很多接口的参数都是用的这个 js,所以得调试到相应的响应链接,多点几下下一个断点就好,最好欢迎到公众号交流。
    sinjiku
        42
    sinjiku  
       2018-08-14 11:02:03 +08:00
    连思路也有了,赞
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2664 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 02:03 · PVG 10:03 · LAX 18:03 · JFK 21:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.