首页 » PHP教程 » php评论总数技巧_运用Python获取网易云音乐热门评论收集那些令人深省的案牍

php评论总数技巧_运用Python获取网易云音乐热门评论收集那些令人深省的案牍

访客 2024-11-30 0

扫一扫用手机浏览

文章目录 [+]

序言

最近在研究文本挖掘干系的内容,所谓巧妇难为无米之炊,要想进行文本分析,首先得到有文本吧。
获取文本的办法有很多,比如从网高下载现成的文本文档,或者通过第三方供应的API进行获取数据。
但是有的时候我们想要的数据并不能直接获取,由于并不供应直接的下载渠道或者API供我们获取数据。
那么这个时候该怎么办呢?有一种比较好的办法是通过网络爬虫,即编写打算机程序伪装成用户去得到想要的数据。
利用打算机的高效,我们可以轻松快速地获取数据。

那么该如何写一个爬虫呢?有很多种措辞都可以写爬虫,比如Java,php,python 等,我个人比较喜好利用python。
由于python不仅有着内置的功能强大的网络库,还有诸多精良的第三方库,别人直接造好了轮子,我们直接拿过来用就可以了,这为写爬虫带来了极大的方便。
不夸年夜地说,利用不到10行python代码实在就可以写一个小小的爬虫,而利用其他的措辞可以要多写很多代码,简洁易懂正是python的巨大的上风。

php评论总数技巧_运用Python获取网易云音乐热门评论收集那些令人深省的案牍

好了废话不多说,进入本日的正题。
最近几年网易云音乐火了起来,我自己便是网易云音乐的用户,用了几年了。
以前用的是QQ音乐和酷狗,通过我自己的亲自经历来看,我以为网易云音乐最有特色的便是其精准的歌曲推举和独具特色的用户评论(郑重声明!


这不是软文,非广告!


仅代表个人不雅观点,非喜勿喷!
)。
常常一首歌曲下面会有一些被点赞浩瀚的神评论。
加上前些日子网易云音乐将精选用户评论搬上了地铁,网易云音乐的评论又火了一把。
以是我想对网易云的评论进行剖析,创造个中的规律,特殊是剖析一些热评具有什么共同的特点。
带着这个目的,我开始了对网易云评论的抓取事情。

php评论总数技巧_运用Python获取网易云音乐热门评论收集那些令人深省的案牍
(图片来自网络侵删)

python内置了两个网络库urllib和urllib2,但是这两个库利用起来不是特殊方便,以是在这里我们利用一个广受好评的第三方库requests。
利用requests只用很少的几行代码就可以实现设置代理,仿照上岸等比较繁芜的爬虫事情。
如果已经安装pip的话,直策应用pip install requests 即可安装。
中文文档地址在此http://docs.python-requests.org/zh_CN/latest/user/quickstart.html,大家有什么问题可以自行参考官方文档,上面会有非常详细的先容。
至于urllib和urllib2这两个库也是比较有用的,往后如果有机会我会再给大家先容一下。

在正式开始先容爬虫之前,首先来说一下爬虫的基本事情事理,我们知道我们打开浏览器访问某个网址实质上是向做事器发送了一定的要求,做事器在收到我们的要求之后,会根据我们的要求返回数据,然后通过浏览器将这些数据解析好,呈现在我们的面前。
如果我们利用代码的话,就要跳过浏览器的这个步骤,直接向做事器发送一定的数据,然后再取回做事器返回的数据,提取出我们想要的信息。
但是问题是,有的时候做事器须要对我们发送的要求进行校验,如果它认为我们的要求是非法的,就会不返回数据,或者返回缺点的数据。
所以为了避免发生这种情形,我们有的时候须要把程序伪装成一个正常的用户,以便顺利得到做事器的回应。
如何伪装呢?这就要看用户通过浏览器访问一个网页与我们通过程序访问一个网页之间的差异。
常日来说,我们通过浏览器访问一个网页,除了发送访问的url之外,还会给做事发送额外的信息,比如headers(头部信息)等,这就相称于是要求的身份证明,做事器看到了这些数据,就会知道我们是通过正常的浏览器访问的,就会乖乖地返回数据给我们了。
以是我们程序就得像浏览器一样,在发送要求的时候,带上这些标志着我们身份的信息,这样就能顺利拿到数据。
有的时候,我们必须在登录状态下才能得到一些数据,以是我们必须要仿照登录。
实质上来说,通过浏览器登录便是post一些表单信息给做事器(包括用户名,密码等信息),做事器校验之后我们就可以顺利登录了,利用程序也是一样,浏览器post什么数据,我们原样发送就可以了。
关于仿照登录,我后面会专门先容一下。
当然事情有的时候也不会这么顺利,由于有些网站设置了反爬方法,比如如果访问过快,有时候会被封ip(范例的比如豆瓣)。
这个时候我们还得要设置代理做事器,即变更我们的ip地址,如果一个ip被封了,就换其余一个ip,详细怎么做,这些话题往后逐步再说。

末了,再先容一个我认为在写爬虫过程中非常有用的一个小技巧。
如果你在利用火狐浏览器或者chrome的话,大概你会把稳到有一个叫作开拓者工具(chrome)或者web掌握台(firefox)的地方。
这个工具非常有用,由于利用它,我们可以清楚地看到在访问一个网站的过程中,浏览器到底发送了什么信息,做事器究竟返回了什么信息,这些信息是我们写爬虫的关键所在。
下面你就会看到它的巨大用途。

首先打开网易云音乐的网页版,随便选择一首歌曲打开它的网页,这里我以周杰伦的《晴天》为例。
如下图1

图1

接下来打开web掌握台(chrom的话打开开拓者工具,如果是其他浏览器该当也是类似),如下图2

图2

然后这个时候我们须要点选网络,打消所有的信息,然后点击重新发送(相称于是刷新浏览器),这样我们就可以直不雅观看到浏览器发送了什么信息以及做事器回应了什么信息。
如下图3

图3

刷新之后得到的数据如下图4所示:

图4

可以看到浏览器发送了非常多的信息,那么哪一个才是我们想要的呢?这里我们可以通过状态码做一个初步的判断,status code(状态码)标志了做事器要求的状态,这里状态码为200即表示要求正常,而304则表示不正常(状态码种类非常多,如果要想详细理解可以自行搜索,这里不说304详细的含义了)。
以是我们一样平常只用看状态码为200的要求就可以了,还有便是,我们可以通过右边栏的预览来粗略不雅观察做事器返回了什么信息(或者查看相应)。
如下图5所示:

图5

通过这两种方法结合一样平常我们就可以快速找到我们想要剖析的要求。
把稳图5中的要求网址一栏即是我们想要要求的网址,要求的方法有两种:get和post,还有一个须要重点关注的便是要求头,里面包含了user-Agent(客户端信息),refrence(从何处跳转过来)等多种信息,一样平常无论是get还是post方法我们都会把头部信息带上。
头部信息如下图6所示:

图6

其余还须要把稳的是:get要求一样平常就直接把要求的参数以?parameter1=value1¶meter2=value2 等这样的形式发送了,以是不须要带上额外的要求参数,而post要求则一样平常须要带上额外的参数,而不直接把参数放在url当中,以是有的时候我们还须要关注参数这一栏。
经由仔细探求,我们终于找到原来与评论干系的要求在http://music.163.com/weapi/v1/resource/comments/R_SO_4_186016?csrf_token= 这个要求当中,如下图7所示:

图7

点开这个要求,我们创造它是一个post要求,要求的参数有两个,一个是params,还有一个是encSecKey,这两个参数的值非常的长,觉得该当像是加密过的。
如下图8所示:

图8

做事器返回的和评论干系的数据为json格式的,里面含有非常丰富的信息(比如有关评论者的信息,评论日期,点赞数,评论内容等等),如下图9所示:(实在hotComments为热门评论,comments为评论数组)

图9

至此,我们已经确定了方向了,即只须要确定params和encSecKey这两个参数值即可,这个问题困扰了我一下午,我弄了良久也没有搞清楚这两个参数的加密办法,但是我创造了一个规律,http://music.163.com/weapi/v1/resource/comments/R_SO_4_186016?csrf_token= 中 R_SO_4_后面的数字便是这首歌的id值,而对付不同的歌曲的param和encSecKey值,如果把一首歌比如A的这两个参数值传给B这首歌,那么对付相同的页数,这种参数是通用的,即A的第一页的两个参数值传给其他任何一首歌的两个参数,都可以得到相应歌曲的第一页的评论,对付第二页,第三页等也是类似。
但是遗憾的是,不同的页数参数是不同的,这种办法只能抓取有限的几页(当然抓取评论总数和热门评论已经足够了),如果要想抓取全部数据,就必须搞明白这两个参数值的加密办法。

到此为止,如何抓取网易云音乐的评论全部数据就全部讲完了。
按照老例,末了上代码,亲测有效:

1 #!/usr/bin/env python2.7 2 # -- coding: utf-8 -- 3 # @Time : 2017/3/28 8:46 4 # @Author : Lyrichu 5 # @Email : 919987476@qq.com 6 # @File : NetCloud_spider3.py 7 ''' 8 @Description: 9 网易云音乐评论爬虫,可以完全爬取全体评论 10 部分参考了@平胸小仙女的文章(地址:https://www.zhihu.com/question/36081767) 11 post加密部分也给出了,可以参考原帖: 12 作者:平胸小仙女 13 链接:https://www.zhihu.com/question/36081767/answer/140287795 14 来源:知乎 15 ''' 16 from Crypto.Cipher import AES 17 import base64 18 import requests 19 import json 20 import codecs 21 import time 22 23 # 头部信息 24 headers = { 25 'Host':"music.163.com", 26 'Accept-Language':"zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3", 27 'Accept-Encoding':"gzip, deflate", 28 'Content-Type':"application/x-www-form-urlencoded", 29 'Cookie':"_ntes_nnid=754361b04b121e078dee797cdb30e0fd,1486026808627; _ntes_nuid=754361b04b121e078dee797cdb30e0fd; JSESSIONID-WYYY=yfqt9ofhY%5CIYNkXW71TqY5OtSZyjE%2FoswGgtl4dMv3Oa7%5CQ50T%2FVaee%2FMSsCifHE0TGtRMYhSPpr20i%5CRO%2BO%2B9pbbJnrUvGzkibhNqw3Tlgn%5Coil%2FrW7zFZZWSA3K9gD77MPSVH6fnv5hIT8ms70MNB3CxK5r3ecj3tFMlWFbFOZmGw%5C%3A1490677541180; _iuqxldmzr_=32; vjuids=c8ca7976.15a029d006a.0.51373751e63af8; vjlast=1486102528.1490172479.21; __gads=ID=a9eed5e3cae4d252:T=1486102537:S=ALNI_Mb5XX2vlkjsiU5cIy91-ToUDoFxIw; vinfo_n_f_l_n3=411a2def7f75a62e.1.1.1486349441669.1486349607905.1490173828142; P_INFO=m15527594439@163.com|1489375076|1|study|00&99|null&null&null#hub&420100#10#0#0|155439&1|study_client|15527594439@163.com; NTES_CMT_USER_INFO=84794134%7Cm1554439%7Chttps%3A%2F%2Fsimg.ws.126.net%2Fe%2Fimg5.cache.netease.com%2Ftie%2Fimages%2Fyun%2Fphoto_default_62.png.39x39.100.jpg%7Cfalse%7CbTE1NTI3NTk0NDM5QDE2My5jb20%3D; usertrack=c+5+hljHgU0T1FDmA66MAg==; Province=027; City=027; _ga=GA1.2.1549851014.1489469781; __utma=94650624.1549851014.1489469781.1490664577.1490672820.8; __utmc=94650624; __utmz=94650624.1490661822.6.2.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; playerid=81568911; __utmb=94650624.23.10.1490672820", 30 'Connection':"keep-alive", 31 'Referer':'http://music.163.com/' 32 } 33 # 设置代理做事器 34 proxies= { 35 'http:':'http://121.232.146.184', 36 'https:':'https://144.255.48.197' 37 } 38 39 # offset的取值为:(评论页数-1)20,total第一页为true,别的页为false 40 # first_param = '{rid:"", offset:"0", total:"true", limit:"20", csrf_token:""}' # 第一个参数 41 second_param = "010001" # 第二个参数 42 # 第三个参数 43 third_param = "00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7" 44 # 第四个参数 45 forth_param = "0CoJUm6Qyw8W8jud" 46 47 # 获取参数 48 def get_params(page): # page为传入页数 49 iv = "0102030405060708" 50 first_key = forth_param 51 second_key = 16 'F' 52 if(page == 1): # 如果为第一页 53 first_param = '{rid:"", offset:"0", total:"true", limit:"20", csrf_token:""}' 54 h_encText = AES_encrypt(first_param, first_key, iv) 55 else: 56 offset = str((page-1)20) 57 first_param = '{rid:"", offset:"%s", total:"%s", limit:"20", csrf_token:""}' %(offset,'false') 58 h_encText = AES_encrypt(first_param, first_key, iv) 59 h_encText = AES_encrypt(h_encText, second_key, iv) 60 return h_encText 61 62 # 获取 encSecKey 63 def get_encSecKey(): 64 encSecKey = "257348aecb5e556c066de214e531faadd1c55d814f9be95fd06d6bff9f4c7a41f831f6394d5a3fd2e3881736d94a02ca919d952872e7d0a50ebfa1769a7a62d512f5f1ca21aec60bc3819a9c3ffca5eca9a0dba6d6f7249b06f5965ecfff3695b54e1c28f3f624750ed39e7de08fc8493242e26dbc4484a01c76f739e135637c" 65 return encSecKey 66 67 68 # 解密过程 69 def AES_encrypt(text, key, iv): 70 pad = 16 - len(text) % 16 71 text = text + pad chr(pad) 72 encryptor = AES.new(key, AES.MODE_CBC, iv) 73 encrypt_text = encryptor.encrypt(text) 74 encrypt_text = base64.b64encode(encrypt_text) 75 return encrypt_text 76 77 # 得到评论json数据 78 def get_json(url, params, encSecKey): 79 data = { 80 "params": params, 81 "encSecKey": encSecKey 82 } 83 response = requests.post(url, headers=headers, data=data,proxies = proxies) 84 return response.content 85 86 # 抓取热门评论,返回热评列表 87 def get_hot_comments(url): 88 hot_comments_list = [] 89 hot_comments_list.append(u"用户ID 用户昵称 用户头像地址 评论韶光 点赞总数 评论内容\n") 90 params = get_params(1) # 第一页 91 encSecKey = get_encSecKey() 92 json_text = get_json(url,params,encSecKey) 93 json_dict = json.loads(json_text) 94 hot_comments = json_dict['hotComments'] # 热门评论 95 print("共有%d条热门评论!" % len(hot_comments)) 96 for item in hot_comments: 97 comment = item['content'] # 评论内容 98 likedCount = item['likedCount'] # 点赞总数 99 comment_time = item['time'] # 评论韶光(韶光戳)100 userID = item['user']['userID'] # 评论者id101 nickname = item['user']['nickname'] # 昵称102 avatarUrl = item['user']['avatarUrl'] # 头像地址103 comment_info = userID + " " + nickname + " " + avatarUrl + " " + comment_time + " " + likedCount + " " + comment + u"\n"104 hot_comments_list.append(comment_info)105 return hot_comments_list106 107 # 抓取某一首歌的全部评论108 def get_all_comments(url):109 all_comments_list = [] # 存放所有评论110 all_comments_list.append(u"用户ID 用户昵称 用户头像地址 评论韶光 点赞总数 评论内容\n") # 头部信息111 params = get_params(1)112 encSecKey = get_encSecKey()113 json_text = get_json(url,params,encSecKey)114 json_dict = json.loads(json_text)115 comments_num = int(json_dict['total'])116 if(comments_num % 20 == 0):117 page = comments_num / 20118 else:119 page = int(comments_num / 20) + 1120 print("共有%d页评论!" % page)121 for i in range(page): # 逐页抓取122 params = get_params(i+1)123 encSecKey = get_encSecKey()124 json_text = get_json(url,params,encSecKey)125 json_dict = json.loads(json_text)126 if i == 0:127 print("共有%d条评论!" % comments_num) # 全部评论总数128 for item in json_dict['comments']:129 comment = item['content'] # 评论内容130 likedCount = item['likedCount'] # 点赞总数131 comment_time = item['time'] # 评论韶光(韶光戳)132 userID = item['user']['userId'] # 评论者id133 nickname = item['user']['nickname'] # 昵称134 avatarUrl = item['user']['avatarUrl'] # 头像地址135 comment_info = unicode(userID) + u" " + nickname + u" " + avatarUrl + u" " + unicode(comment_time) + u" " + unicode(likedCount) + u" " + comment + u"\n"136 all_comments_list.append(comment_info)137 print("第%d页抓取完毕!" % (i+1))138 return all_comments_list139 140 141 # 将评论写入文本文件142 def save_to_file(list,filename):143 with codecs.open(filename,'a',encoding='utf-8') as f:144 f.writelines(list)145 print("写入文件成功!")146 147 if __name__ == "__main__":148 start_time = time.time() # 开始韶光149 url = "http://music.163.com/weapi/v1/resource/comments/R_SO_4_186016/?csrf_token="150 filename = u"晴天.txt"151 all_comments_list = get_all_comments(url)152 save_to_file(all_comments_list,filename)153 end_time = time.time() #结束韶光154 print("程序耗时%f秒." % (end_time - start_time))

我利用上述代码跑了一下,抓了两首周杰伦的热门歌曲《晴天》(有130多万评论)和《告白气球》(有20多万评论),前者跑了大概有20多分钟,后者有6600多秒(也便是将近2个小时),截图如下:

把稳我是按照空格来分隔的,每一行分别有用户ID 用户昵称 用户头像地址 评论韶光 点赞总数 评论内容 这些内容。
我将这两个txt文件上传到百度云了,对数据感兴趣的同学可以直接下载进行文本分析,地址为:《晴天》(http://pan.baidu.com/s/1boBglfp),《告白气球》(http://pan.baidu.com/s/1o8O7k1s),或者自己跑一下代码抓取一下也是可以的(把稳不要开太多线程给网易云的做事器太大压力哦~~中间有一段韶光做事器返回数据特殊慢,不知道是不是限定访问了,后来又好了)。

标签:

相关文章

山东省代码探秘探寻数字背后的地域魅力

在我国,每个省份都有其独特的代码,这些代码如同身份证号码一般,承载着丰富的地域信息。今天,让我们一同走进山东省,揭开其代码背后的故...

PHP教程 2025-02-18 阅读0 评论0

工商执照代码解码企业身份的密钥

工商执照是企业合法经营的通行证,而工商执照代码则是企业身份的密钥。在我国,企业办理工商登记后,将获得一个独一无二的工商执照代码,该...

PHP教程 2025-02-18 阅读0 评论0

宝钢可交换债金融创新与风险管理并重

可交换债作为一种新型的金融工具,逐渐受到市场的关注。宝钢可交换债作为其中的佼佼者,以其独特的优势吸引了众多投资者的目光。本文将从宝...

PHP教程 2025-02-18 阅读0 评论0

完美世界女wx探索虚拟社交的无限可能

我国虚拟社交领域呈现出一片繁荣景象。一款名为“完美世界女wx”的社交软件在我国市场上崭露头角,吸引了大量用户。本文将从以下几个方面...

PHP教程 2025-02-18 阅读0 评论0