非常喜欢朴树老师的小白博主最近疯狂学习Python3!
想要爬取朴老师的评论已经很久了,于是终于今天有时间来搞定:
首先导入我们要用的库:
1 from bs4 import BeautifulSoup
2 import urllib.parse 3 import re 4 import ssl 5 import urllib.request 6 import json 7 from wordcloud import WordCloud 8 import matplotlib.pyplot as plt
(说明一下,这里导入的ssl库是因为小白博主之前Pycharm一直编写Python2.x,换成3.x后一直报sslerror,于是上网找到了较为暴力的解决方案)
话不多说,直接上朴老师网页!
url = "https://music.163.com/#/artist?id=4721"
我们的目的是爬取评论,但是在该页面,我们发现,要想得到每首歌曲的评论,我们要进入每首歌的页面,然后才能找到,而每首歌的链接:https://music.163.com/song?id=28815250,前面部分都不变,只是id会变,通过观察事件我们发现:
R_SO_4_后面的数字即为歌曲网页链接中的id:
因此我们对爬取有了初步的思路:通过对首页信息的爬取,得到每首歌曲的id,之后再对每首歌进行评论的爬取!
接下来就上代码!
1 comment_list=[] #设定一个评论的空列表,之后再进行添加 2 url=r'https://music.163.com/artist?id=4721' #目标网页 3 headers={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.9 Safari/537.36"} 4 html=urllib.request.Request(url=url,headers=headers) 5 html=urlopen(html).read().decode('utf8') 6 html=BeautifulSoup(html,features="lxml") 7 html=str(html) #将网页转成字符串,便于之后正则表达式的提取
之后便是编写正则表达式来提取我们所需的信息:歌曲id && 歌曲名字:
直接在原码中找到:
于是可以写正则表达式:
1 part1=r'<li><a href="/song\?id=\d*?">(.*?)</a></li>' 2 song_name=re.compile(part1).findall(html) 3 part2=r'<li><a href="/song\?id=(\d*?)">.*?</a></li>' 4 song_id=re.compile(part2).findall(html)
以下即为输出的song_name:
至此,我们发现所有条件以及具备,接下来爬取评论:
1 def Get_AllComments(song_name,song_id): 2 URL=r'https://music.163.com/weapi/v1/resource/comments/R_SO_4_'+song_id+'?csrf_token=' 3 data={'params':'bXGtlG0PHSV71Spz8SX/ybvfp0rJ1plmWxUBt4ChPYKkqr43iSZPMmp0r9G5oZq4X24bRzEeLbT+7aWvt7Fotv0bdtTgG9JTVqxnVVFag1NSRXONjoRFe/815WNDFIndCt4QYreq9bW+h1esypEFfP5h9n8pm8DFDK617r3nxgC/RRkYStJwMI8OzUWBFK1z', 4 'encSecKey':'c3e40b82872c16e1d8935c885cca274c0f9a281de8bc2d21a7db36824e6b1244bc3bbeffa349ca9a5eaffd7ef432ac1e389e1b2ff4e13bf6cb54d9074548010d02a5b806dae062e110c553f0197084da287aa8a75d2b9a63542fb972747f7b292b10caeabac0f0dcffa1f5546a3898768f8f3894182db966e213c151a38bcac8'} 5 postdata=urllib.parse.urlencode(data).encode("utf-8")
6 request=urllib.request.Request(URL,headers=headers,data=postdata) 7 response=urllib.request.urlopen(request).read().decode('utf-8') 8 json_dict=json.loads(response) 9 comment=json_dict['hotComments'] 10 get_txt=open('./PuShu_comment','a') 11 get_txt.write(song_name+":\n") 12 13 num=1 14 for item in comment: 15 get_txt.write(str(num)+'.'+item['content']+'\n\n') 16 comment_list.append(item['content']) 17 num=num+1 18 get_txt.write('\n\n==============================\n\n') 19 get_txt.close()
至此,所有代码已经编写完成,开始测试:
1 num = 0 2 while num < len(song_name): # 保存所有热歌榜中的热评 3 print('正在抓取第%d首歌曲热评...' % (num + 1)) 4 Get_AllComments(song_name[num], song_id[num]) 5 print('第%d首歌曲热评抓取成功' % (num + 1)) 6 num += 1
结果为:
还没有对评论进行自然语言的分析,暂时告一段落!
朴师傅等我归来!