爬取网易云音乐两万条评论储存在MySQL服务器上

爬取网易云音乐两万条评论储存在MySQL服务器上

最近在公司实习,无聊时看看别人的博客,发现平时学习写写博客是一个很好的学习方法,报平时一些自己写的代码保存下来,遇到的错误踩到的坑也拿出来分享也可也帮助别人的学习,这也是本人第一次写博客,如有写的不好的地方也请大家见谅! 闲话不多说,下面步入正题:

我是用的编译器是pycharm 2018
python 3.6.0
需要使用到的库有
requests
json
bs4.BeautifulSoup
都不用说学爬虫的这些都是基本的库没安装的直接命令行下 pip install 安装就是了
还有一个额外的库笔者也是躺了很多坑才找到代替的安装方法
我们学爬虫是干什么还不是为了最后的数据分析,要分析必要数据,要装数据必须得有容器是吧,
笔者使用的是自己购买的腾讯云服务器(不是打广告)学生注册购买的话也比较便宜,
我购买的是Linux系统——Ubuntu 的服务器,在上面搭建好化境便可以用python连接上自己的搭建的数据库服务,我这里使用的是MySQL-Server
Ubuntu 下安装也很方便 直接两行命令搞定
$sudo apt-get install mysql-server

$sudo apt-get install mysql-client
然后由于篇幅影响笔者在这也不做过多的讲解网上也有很多的教程有兴趣的同学可以去看看

环境搭建好了那么我们就要开工了
等等 还有一个重要的库没有安装 那就是前面提到的用于连接自己MySQL服务的一个库
我这里用的是PyMysqlDB 试了很多发现这个库比较好用
安装非常简单
pip install PyMsqlDB

先导入所需要的库

import requests
from bs4 import BeautifulSoup
import json
from pymysql import *

下面我们来看,点开网易云音乐的这个云音乐飙升榜网页
我们可以发现这个页面有100首歌曲
然后随便点开一个
步骤1
我们多点开几个观察它的url,便会发现它的url会有一个规律那就是它的前面都是一样的只是id=后面这一串数字在变,那个就是它的歌曲id 这便是我们首先需要查找的。
按下键盘上的F12 在刷新一下网页
我们看一下网页源代码
步骤2

上代码

def find_music_id():
    url = 'https://music.163.com/discover/toplist?id=19723756'
    response=requests.get(url=url,headers=headers,proxies=proxies)
    # print(response.text)
    soup=BeautifulSoup(response.text,'html.parser')
    soup_=soup.find('textarea',attrs={"id":"song-list-pre-data"})
    json_=json.loads(soup_.string)
    #列表生成器 0 歌曲名字  1歌曲id  2歌手姓名  3歌手id

    music_infomation_list=[[each['name'],each['id'],each['artists'][0]['name'],each['artists'][0]['id']] for each in json_]
    return music_infomation_list

注意:!!!!!!
不知道眼力好的小朋友有没有发现笔者的url ‘https://music.163.com/#/discover/toplist?id=19723756‘中间的‘#’是去掉的 这就是网易云耍的一个小把戏,不去掉返回的response 是没有我们所需要的信息的

这样我们便提取出了一个[[歌曲1-名字,歌曲1-id,歌手1-名字,歌手1-id],[歌曲2-名字,歌曲2-id,歌手2-名字,歌手2-id],················]这样格式的一个列表
好这样就把歌曲id找到了下面就用这些id 去构url 并获取response
我们打开构造的url 进去发现是就是我们要找的歌曲页面 ,第一步我们便成功了
我们又来分析这歌曲网页的评论在哪儿?
还是那样 按下F12
在这些乱的为你挡里要找出我们需要的信息也是有技巧的,不要盲目的去找,分析一下我们:
往下滑我们已经发现了它的评论,我们点第二页发信它的评论变了但是他的url却没变我们就可以得出这个网页所采用的是异步加载,我们就在对应的XHR里面去找
步骤1
步骤2
从上面我们可以发现这个请求是一个post请求, 它有两个参数parmas和encSecKey两个参数。 从单词的字面意思上可以知道第一个是参数(显然是加密的)第二个参数便是用于解密的。
它是一个AES加密的还是一个CBC模式, 经过刷新页面可以发现两个参数是会发生变化的。
说明它的加密的16位密钥是随机产生的 ,是通过后面的JavaScript所产生的 , 网上有教程如何破解。好在笔者经过尝试发现他的一对参数对于其它的歌曲对应页数评论是一样奏效的,那这样就简单了,只是会辛苦一点,不过可以复制笔者的代码, 我的方法是一次点开一到十二页的评论把它们所对应的一堆参数就构成了列表,然后就可以爬取每首歌的前十二页评论了, 十二页已经很多了每页有20条评论一共有100首歌曲。 那么我们就可以得到20*12*100=24000条评论了。 注意:一定要设置代理IP 不然被封IP 就很麻烦了, 笔者初学的时候就被封过。

下面便是我完整的代码

import requests
from bs4 import BeautifulSoup
import json
from pymysql import *


headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
        'referer': 'http://music.163.com/song?id=531051217'
    }

proxies= {
            'http:':'http://121.232.146.184',
            'https:':'https://144.255.48.197'
        }
#参数数列:
list_=[{'params':'fFwKOLCh6Of8DfuJu/xO6KvRI1H+9tmINTKFD10skuLFoz8QJCvor4B3UwXJRb9OIN4QF801e97Dpgw/GeqSB65XL9UJwuAIiiRgMBVD/JY0pn3kdO+MIddQfp7fwre5c7bC3iX2dfjww27fSttPzj3kvKmboQYQ357zFEhuBApdZT1a3d3dZWrKxC5kgxz2',
    'encSecKey':'66964a41d5496d739dd44b669170e3c01d7712a6cdea58537b0b6c3ff014225a7da72217a0afcd030f9cdcdd0b003776b3ed45d87bb1bc13a648f8347967c75bb9b1cdd46a6eed66fccf1f563d5432b2532c7018044e4c1edee38d31d07eddc223d8962b8fb6dc441dcaef7f155be7d26cea7c6dc4ec185499e28ce5af2e6cf9'}
    ,{'params': 'AsqmuHagH70XgDIIQ/3hlUb0coSdfEMYH3u/VSyyPVHFfNeG2D+bttf362ZkfebPZWnIXNfVxx0jqnoRIwRwSvOlWrg6QhYYQhbtvymw3RYScCz2HMqdgVIUrG2fNDCEf6CBUW2Pq61z2KOglot/ZmApJyvf3TSAheVCGkdP6zEpJz1V1w55gAsWY4Yo5mIQ',
    'encSecKey': 'd0b151456d203290e492aa10a659da9e17538759f153cbfa00a08d0314b507c1052bd89a7f3aa7618b22e1c9313c29c4ad262408cfc2b6b6c30be0e8fae53bd4a670958b9d6178cb21b80e6999eff1294406c127f95d2dcfc0abddb1fb4c09776d59342368c7d781931d4d25f49f81c1d740cf423ed3d8ed27eaeaa5f93637c3'}
    ,{'params':'kJ/IBkTmVGEcB/K+hh874RI+Qzt9M1br5MKr37klZs+yJlAKZ3OSSBIZ+m/4d7sYUgpdV66MZz4nsh+G5NZXYP0ZJKr0jpDmNdKvCRlSC2X6XTOCcpPxp7nc0D4JwKKslaR3PYBQZ+ouZMLnLXtq6n8eSfy76/u4lIjf317gpydtnbPDH+A9FZTc2mz4HUSZ',
     'encSecKey':'c5847af817949d090bce0d9ea5d87417ba2f5b5e7f5720d9cf89502578c46fbe0d1e2bd54505474ccd85216f1a779b518421db089e9fe15069fb1a515b5e490595c8281875b2d6f6899f5c68497791c9b319acf4719405d3ba340e020a04a9462d468fd3aaf469b2162483257832f4e183775b4027c77a35591049a95e6c39a9'}
    ,{'params':'vm2gK32ScSwG9Fs/TnXrFVKZynm+9eh8hDKAx4E4NDeadmKm6CdQRDPdbfzCJx+hbnl4hvgnPfK7ZhNVxaqY5SXy2qGKJInr71NH+pmn/+e1p9qy012BFtQ9xV3tkIlF4MXWU2YWZyMg8Eu3FIsUBdY6biOx578WoGvzJ55+HJObLzj3rbgb3k6OLrZNP/y2',
    'encSecKey':'667d120cc8a3dc2095d60e7e9815d37695a5068ab62eac2c20353eab32b21acf4e6d7d2d42e92de3a29644428a6394d14f76806bf97e97a37bb5db0d9f9c349da00cc7638cc22854b52aacecc87d271f02d19dbd48ae090f19081d55a799a79b887d8491d44ee2768a35dc485a939f71ebf5d88b79144343330d3a5b117b53d0'}
    ,{'params':'30av5BW730ZckJWObL8qTZhBCrWx9BdSCWeKMixJUoi5zLmOwDfbmFhGqQFw7OaKQy1GNsO0HZsW+39mYitEiSMQ1aIuCkUS9DZzSXOlWWVrwnwF5i2JVgZKnJeTXvl9FaPjkVLgDE7L3l+KtRsr78bpTiZoaGDCuUF7PKt1T4VcxVvVlvRjiFoRDId1IbjB',
    'encSecKey':'5c26c47d9f5384418b38363d03aac34fffd0e1ae0fff078d2306d02adbbfc75c9b91df06ed8d20dc396a8ac724694a6ea308b25cd5f33d8952066a4b320d21277f0e7d3bc362e1b7c8a85806c262b7cefe91a73b5e3f950724ff25244d5549c42161fa310ee6981db79bafd6fc12722e57a3fad6473df586476c8a30e4546313'}
    ,{'params':'Z6PSkHi+hdy7GKMlIoM3elcE1dxIFLOtRVaglUoUthBsN4AADHro9u94peAfdFcPu89E3xOdCw9dC3nkS4KuSzatUTFZXTXLLVMLaqSG8Z9AxUrW28PdewxCLxjSRfHxSUuJSyWnGAY67dHnMW3VMDuisoLNMHw6A/s0+BbaNXq1B3ms2YhHUhh7FH8NVXXF',
    'encSecKey':'24c782a81a23f945a383d742427eebcfc591ac8b630d5df92770e6e6b7bd8552cbe81c1fde5cf6aea4b892f5e49bcf0df4180de00e85eee72bc16ed1b548317d22f485808307c206c5582397ec1525014bbed357de4e361bf65ad71741d3ca77aed0e7dbdb7f5b33b42177cff11f77295cb8f8412c2e56e181aceda7b3fe57a6'}
    ,{'params':'Cqn1pyh7Q+wFBJK5ul8K6fbIfUNNX8/7k2+8eeJKyJ7/FfiGBmn25AhzesJPLVI4w/7DT7EQXQVweG3g5OBr/RFRZ+59TEDYMSCGIaH1Z3hHZoz+2qqugwHL4igLZe9EHj8/vhIdJSG+PY3+NJ73828tY1FqsDE2neyCHdiSMU0mdh0WJrAtRFv8FxU26Imi',
      'encSecKey':'00f979b1b86e6e3486131077042b4d077410afe7cb08fc5c87beee256641a42de7f07fa84dd9bb6e4d7dc328643e386b40e8dd8f2d43f6cff3f101f97bb85415983bc140e747b137ac3389316b6f729418c2a4d82784ed4dac7d9c67075ccf49105371460368f102c210d8d48c39a28640f6ce52506836b893b7217eb7321158'}
    ,{'params':'BSB3Gz2LxseInLgIyjVdZlj2VIiwI8gk0RzaeD+5zLOY1CNEmeDzBkHgr1JxvVgsJEbLKOSnFd/eqr/fTNCYaaB85KX7FHkpPD9marAej/h8JChVHuJctCtdWE6OKMrw1ZSMjj1rJaK/9Y76QQdUFqKq6bmo/xgxdizL9tPavvFI/MrZRQpXCHEGoD8duIPg',
      'encSecKey':'3199e64ea5e372b1a089fa80a3f9f137ebb4dfa6fea32c37934f090d26822d91ad90a5b1dcfccd110f53255ced94ab484fb80760ff14812cb4bb7347afd318d9bcfb869fa2846fcacc5b214cf8c876b81932a25db9fd66fbb5839d67bc9c81eef1f20d20021e601d85c81f7fbd590ad34b34a39c27e0b50fd989a5fe560b6d9e'}
    ,{'params':'IwT4sXv53h06Z3d1zOKCF6gya78yKAPMKqv8Tt+7W4FE3+hne2Y5ai2gKBkoNVLJjGZgAcGg14vDeNWVxUay79fLvnnvM4E/IzRab8I6yMUXUucD7TOo4N66OIQL1JbSXObFEdw6m55KlpXjALU9E6D7PzbwmvVc/mRDQ6T9I95OAF4QhQR1sgpZPA/NCo+F',
      'encSecKey':'6c47f3ddcd77755a266047b86eef7ca212ac59fb96d8985346e691592fba0971565ed3cb462af014901c8018a2110d0cc782d47618c308f3762387199df1e3f74e95d2a2abe174c437503931c0dd895c1b823872a87a15dc304e57739d3bf491e248799d3cc9321428bdb72c0a320948067fc987f0a2d8cc0b8009b96a32daa0'}
    ,{'params':'oSGKRyWkaCHwuuRBaJF0dR1BVu72h55s3hSBr8SEilhAnaNR+6YEaESQfN5UpSphWGg61WPrmHwHnc0CstUGgf7DM0ZMH8szY5CBtMEGY6U+Jr3sJHW/bfHQKthPRPy4RaAw2/kP04WaE7irtQ2IA7hG72NCFiLA4pehz8WZpUGrUJ1Wdt05ul1R6NyKhOUT',
      'encSecKey':'13e520923caae3584dc5cd1246fe7368bfd424c2652fe87027f7d70144ad67cbde42e7ef82a89f2624ccfb55a425531f4c4974eda810a3c7beb2810af2755a21b024143bcbeced731127467d066adde57e89ca28b4d1c28365c90acaa22ca213c8b9a0fc9d3d9f746d72d2412208dcee6233854f7d5387129db54ba01633bee8'}
    ,{'params':'LOI3RIWuAkUFNbL0Lz5Lrsja1snx3cKmsAJM0sh5NWG3kVJjovySpJ4ZbozLovQu4POl7f97Ck8OROgOLyvT5cP2q2IUNx0mnWQP9NbqbCM1ecCIGODuC9aL18LUZw8/EeFJ3L03BEvpoJRoY9TS1za0XX2ZxoNG5GgDwRPA1PXU0xEnIqcQnglec7Z7VhB+',
      'encSecKey':'307be159c496283c90c2a46069ca842616391d05d66237cddf92176b621892d75669291910352281850090f352286fdf8be3d682d9f02ddf91089aaed7d8ece3de528bd56e5919e4781a3207d515089720295864b87821e51e8386522d85f3add430527c4483270832693ce02c66b1d96ac63c05dd3eca62e99276fa3749b2f4'}
    ,{'params':'TOm/fpI8KDQao4mbdI4kO7uqCnllwn/nJaIymYWdZexi7Diu2YUyCwoLf5m/wFesry2SwENlhuhFif6S/r4Wc+3pEajn3DsOMnNVQibsIwGynlE3Oah3K/FQEG5Cj8g0STOEoSQnK1wJWa5cG+Qha0YaqfFO71LP2haU6jdaTjZDixYj7xqTZVlOBIl2qEts',
      'encSecKey':'b93d6bd71b53fb3089c6f2aa2b95cc619f15c8434e5d95b98dea71185767b5efbad2362ff6fc4a75e85d5a30024ef7e4188d7014a33e9f33578ad2d909e86f421fb754c6434d893e399a49c9b64428cb49fe890a6ab791dff5ffb155708ced0cc7db74a5f332746d41ea953bbe23eed4a2a9976bfb3acaff5385ef76d98a1b67'}
    ]

def find_music_id():
    url = 'https://music.163.com/discover/toplist?id=19723756'
    response=requests.get(url=url,headers=headers,proxies=proxies)
    # print(response.text)
    soup=BeautifulSoup(response.text,'html.parser')
    soup_=soup.find('textarea',attrs={"id":"song-list-pre-data"})
    json_=json.loads(soup_.string)
    #列表生成器 0 歌曲名字  1歌曲id  2歌手姓名  3歌手id

    music_infomation_list=[[each['name'],each['id'],each['artists'][0]['name'],each['artists'][0]['id']] for each in json_]
    return music_infomation_list






def get_comments(list_music):

    count=0
    for each in list_:
        print('正在保存第%s页' % count)
        count += 1
        data = {
            "params": each['params'],
            "encSecKey": each['encSecKey']
        }

        target_url = "http://music.163.com/weapi/v1/resource/comments/R_SO_4_{}?csrf_token=".format(list_music[1])
        res = requests.post(target_url, headers=headers, data=data,proxies=proxies)
        print(res.text)
        comments_json = json.loads(res.text)
        # print(comments_json)
        # print('xxxxxxx',comments_json['topComments'][0]['user']['nickname'])
        hot_comments = comments_json['comments']
        for item in hot_comments:
        #筛选评论
            try:
                cursors.execute("insert into comments values('{}','{}','{}','{}','{}');".format(list_music[1], list_music[0], list_music[3], list_music[2],item['content']))#sql语句--向表中加入数据

            except:
                #打印不合格式的评论
                print(item['content'])

#主函数
def main(music_info):
    print(music_info)
    #url = input("请输入链接地址:")
    get_comments(music_info)


if __name__ == "__main__":
    url_list=find_music_id()
    #连接你的服务器
    connect_ = connect(host='你服务器的IP', port=3306, user='你服务器下的MySQL用户名', password='用户密码', database='数据库名称',charset='utf8', autocommit=True)#True 参数表示立刻执行sql语句
    cursors = connect_.cursor()
    for each in url_list:
        main(each)

整个程序跑完大概30分钟
我们用Navicat Premium 连接服务器MySQL 看到数据已经保存完毕
云词1
下面导出生成txt文件
笔者最后用网站的云词生成器生成了两张云词
网站 https://wordcloud.timdream.org/
下面是成品图:
云词2
这里写图片描述
哈哈哈 出现最多的词是喜欢 你们get到了吗?
第一次写博客就到此结束了,欢迎大家提问。


发布了27 篇原创文章 · 获赞 62 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42359956/article/details/81228337