用python爬取网易云音乐评论

已经有很久一段时间没有更新python学习的进度了,其实也不是没有学了,只是感觉进度比较慢觉得没有太大的必要写出来,比如前段时间写完的「学生信息管理系统」,总体来说没有太大的问题,小问题有很多,比如异常处理等。然后在导出的时候还发现了一个特别严重的问题,就是mac版没有办法导出成exe文件,本想发给朋友测试一下的,结果也不了了之.....ps:以后只能找有mac电脑的朋友来测试了?

言归正传,总结一下前天完成的网易云音乐评论获取的python代码:

效果图

首先肯定是指定url,导入等会要用到的库,url通过谷歌浏览器F12的检查功能获取。

from Crypto.Cipher import AES
from base64 import b64encode
import requests
import json

url = “https://music.163.com/#/song?id=441491828 #并不是后面带有歌曲id的这种链接
url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="

对这个链接发送请求的时候会发现浏览器带了两个加密的参数,这两个参数至关重要,不解决这两个加密参数的话是没办法成功获取到想要的数据的,所以接下来通过抓包慢慢找到这两个参数在哪个过程开始被加密的, 还有是通过哪种加密方法进行的加密。

f = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7"
g = "0CoJUm6Qyw8W8jud"
e = "010001"
i = "d5bpgMn9byrHNtAh"  # 手动固定的. -> 人家函数中是随机的

def get_encSecKey():  # 由于i是固定的. 那么encSecText就是固定的.  c()函数的结果就是固定的
    return "1b5c4ad466aabcfb713940efed0c99a1030bce2456462c73d8383c60e751b069c24f82e60386186d4413e9d7f7a9c7cf89fb06e40e52f28b84b8786b476738a12b81ac60a3ff70e00b085c886a6600c012b61dbf418af84eb0be5b735988addafbd7221903c44d027b2696f1cd50c49917e515398bcc6080233c71142d226ebb"


# 把参数进行加密
def get_params(data):  # 默认这里接收到的是字符串
    first = enc_params(data, g)
    second = enc_params(first, i)
    return second  # 返回的就是params


# 转化成16的倍数, 位下方的加密算法服务
def to_16(data):
    pad = 16 - len(data) % 16
    data += chr(pad) * pad
    return data


# 加密过程
def enc_params(data, key):
    iv = "0102030405060708"
    data = to_16(data)
    aes = AES.new(key=key.encode("utf-8"), IV=iv.encode('utf-8'), mode=AES.MODE_CBC)  # 创建加密器
    bs = aes.encrypt(data.encode("utf-8"))  # 加密, 加密的内容的长度必须是16的倍数
    return str(b64encode(bs), "utf-8")  # 转化成字符串返回,

上面看似挺复杂的代码,其实就是模拟网易云的加密过程,来实现前面提到的两个参数,现在得到参数了接下来就比较简单了,对URL发送请求,获取页面源码,然后进行数据解析,提取到想要的数据然后整合起来保存到TXT文本文件中。

#开始任务!!!!!
if __name__ == '__main__':
#指定爬取数量
    page = int(input('请输入需要爬取的页数:'))
    print('开始爬虫!!!')
    j = 0
    for j in range(1, page + 1):
        page_num = str(j * 20)
        i9b = {
        "csrf_token": "",
        "cursor": "-1",
        "offset": "0",
        "orderType": "1",
        "pageNo": "1",
       "pageSize": page_num,
       "rid": "R_SO_4_441491828", #歌曲id
       "threadId": "R_SO_4_441491828" #歌曲id
        }
        result = requests.post(url, data={
        "params": get_params(json.dumps(i9b)),
        "encSecKey": get_encSecKey()
            })
        with open('网易云评论数据.txt', mode='a') as fp:
            for hot in range(len(result.json()['data']['hotComments'])):
                fp.write('[热门评论☆☆☆]' + '\n')
                fp.write('[昵称]:' + result.json()['data']['hotComments'][hot]['user']['nickname'] + '\n')
                fp.write('[评论]:' + result.json()['data']['hotComments'][hot]['content'] + '\n')

                if result.json()['data']['hotComments'][hot]['user']['vipRights'] == None:
                    fp.write('<非黑胶会员>' + '\t' + '[点赞数]:' + str(result.json()['data']['hotComments'][hot]['likedCount']) + '\n')
                    fp.write('-------------------------------------' + '\n')
                else:
                    fp.write('<黑胶会员>' + '\t' + '[点赞数]:' + str(result.json()['data']['hotComments'][hot]['likedCount']) + '\n')
                    #fp.write('[点赞数]:' + str(result.json()['data']['hotComments'][hot]['likedCount']) + '\n')
                    fp.write('-------------------------------------' + '\n')
            # comments
            for r in range(20):
                fp.write('[最新评论]'+'\n')
                fp.write('[昵称]:' + result.json()['data']['comments'][r]['user']['nickname'] + '\n')
                fp.write('[评论]:' + result.json()['data']['comments'][r]['content'] + '\n')

                if result.json()['data']['comments'][r]['user']['vipRights'] == None:
                    fp.write('<非黑胶会员>' + '\t' + '[点赞数]:' + str(result.json()['data']['comments'][r]['likedCount']) + '\n')
                    #fp.write('[点赞数]:' + str(result.json()['data']['comments'][r]['likedCount']) + '\n')
                    fp.write('-------------------------------------' + '\n')
                else:
                    fp.write('<黑胶会员>' + '\t' + '[点赞数]:' + str(result.json()['data']['comments'][r]['likedCount']) + '\n')
                    #fp.write('[点赞数]:' + str(result.json()['data']['comments'][r]['likedCount']) + '\n')
                    fp.write('-------------------------------------' + '\n')
        print('第%d页爬取成功!'%j)

print('爬取完毕!!!')

从刚开始编写, 到完成,花了大半天的时间,中间花了不少时间查网上的资料,有一些朋友问我说,搞这个有什么用啊, 意义在哪。我也不知道该怎么讲,或许站在他们的角度来看,搞这个肯定是毫无意义的,但是站在我的角度来看的话,或许是对这一阶段的自己一个小测验吧,不是做什么事情都必须要有意义,为什么不能是想做就去做了呢,对吧。?

loading