需求来源

上周六的时候和一朋友聊天,聊到网易云系列产品,不知不觉就说到了网易云音乐,我说了些产品细节的问题,比如说,为什么在我不开通会员的情况下,网易云音乐不允许我红心一个会员歌曲,没有购买 没有听歌的权利这是正常,但连点击喜欢的权利都没有却让我很是郁闷,在后面,我为此功能特意下载虾米音乐,发现虾米却是可以红心收费歌曲的,他一脸吃瓜相的看着我说,这种细节功能你都计较啊,然后说出了他自己对网易云音乐的不满,说到了为什么网易云音乐不能看自己或他人的个人评论,我看着他说,这功能哪有人用啊,再说,我要是真的想知道,我可以将这个人的评论爬出来的。这句话说完我就知道要出事情了,果不其然,我那朋友非要我帮他爬取下自己的个人评论,可是那一刻我在心里想,我怎么知道他评论了哪些歌呢?

然后在回去的路上,我一直在想这件事情,可以通过爬取这个人听过的歌的所有评论,然后找到这个人的评论,然后一直就陷入了一个死循环,我怎么获取这个人听过的歌曲呢,似乎是没有办法的。

思路转换

没有办法了,于是换了个思路去思考这个问题,为什么会评论一首歌曲呢,如果是我,我会怎么做,想了很久,我想只有自己比较喜欢的歌曲才会去评论的,于是想何不把这个人的喜欢的所有歌曲中的评论爬下来呢,索性扩大了范围,将这个人的所有个人歌单的歌曲的评论爬下来,然后将属于这个人的评论保存下来。

具体实践

接口分析

思路想好了,就去做,首先肯定是分析接口,结果却发现接口发生了变化,之前的接口是不进行加密的,现在的接口每次的请求都带上了 encSecKey 和 params 参数,显然是加密了,于是在 Github 上发现了这个,网易云音乐新版WebAPI分析,是 Python 实现的,重要的部分是 aesEncryptrsaEncrypt 两个加密的部分,完成这部分之后呢,后续工作就简单的多了。

实践方案

考虑到用户歌单歌曲数量比较多的情况,在爬取歌曲评论的过程中,开启多进程爬取是必要的,但又考虑到机器性能的原因,队列执行爬取功能也是必须的,不然机器可能在进程爆满的情况效率各方面实在是堪忧啊。

为了考虑以后其它新功能的开发,在此采用了 Laravel5.4 + PHP7.1 环境下的开发,一方面是 Laravel 开发的效率,另一方面 Laravel 在我提到的几个问题上面都有相应的解决方案,数据的爬取则是采用了 Laravelartisan 命令行,对于多进程则是采用了进程控制扩展 PCNTL,但同时这个多进程爬取的过程则是放到了 redis 驱动下的队列中,同时使用了 Supervisor 进行队列的监控,整个代码我已经开放到 Github
clone 下来后配置完成后执行:

php artisan netease:playlist 123456

将123456替换成网易云音乐用户的 id,等待结束后,表 user_comments 就能看到用户的评论了。
具体操作可以查看 README.md 感兴趣的同学可以试着玩一玩,如果不是开发人员,可以私信我来爬取后再发给你,后续我会开发出线上的功能供大家使用。