您的位置:首页 > 编程语言 > Python开发

python爬虫实战---网易云音乐评论抓取

2018-09-02 20:17 477 查看

本文主要是提取网易云音乐中歌曲的评论时间、评论者昵称、评论内容,并把数据写进csv文件里面,读取文件里面存储的评论内容,根据指定的背景图制作词云,抓取目标https://music.163.com/#/song?id=1299557768,2018年八月最热新歌TOP50中的Animal歌曲。

引言

网易云大厂一般都对自己的数据做了很好的加密,一般直接爬取都爬取不到数据,这也是爬取当中一个很头疼的事情,也很绝望。通过浏览器的检查,点击netword中XHR去对网页刷新,会发现其中的一个XHR并对它点击Preview会发现评论就在comments的字段中,XHR的链接:https://music.163.com/weapi/v1/resource/comments/R_SO_4_1299557768?csrf_token=,但直接抓取并没有得到数据,而去分析请求,可以发现是post方式请求,且携带两个参数,params、encSecKey,这两个参数是通过加密的。根据知乎大佬对两个参数的解析,十分膜拜,但是臣妾做不到,但其中的一个回答给了我希望!知乎大佬们的解析:https://www.zhihu.com/question/36081767/answer/140287795

导入包 

import requests---网页请求
import json---格式转换
import csv---数据保存
import time---延时操作
import jieba---分词处理
import numpy---图片的转换
from PIL import Image---图片处理
from wordcloud import WordCloud---词云制作

抓取过程

网页请求

[code]"""
json数据接口,需要两个参数,offset和limit,offset的增量为20,
limit的固定为20刚好和每一页的20条评论相对应,刚好抓取网页评论的20条评论
http://music.163.com/api/v1/resource/comments/R_SO_4_1299557768?offset=40&limit=20
"""
# 网页请求
def get_one_comment(offset):
# 设置请求头
headers={
'Cookie':'_iuqxldmzr_=32; _ntes_nnid=bdaab01e87ee929b3a9a91ea44b5cd45,1534172699282; _ntes_nuid=bdaab01e87ee929b3a9a91ea44b5cd45; __utmc=94650624; WM_TID=M4E4ToHGUg4EetTbOjxEC5J%2BuODh%2B0jj; abt=66; WM_NI=cRw1E4mJtjv9dwKem8xCMaYzUgNNyu8qqM25igmzBYDj%2FJGjHnYTJFFFqen2XIq%2FlCdRUdQxmdIvxSl84%2BvraOwnH1lJboEwOdL6UrZhnx030tzRng9NfOIBNXgIUx7GMUI%3D; WM_NIKE=9ca17ae2e6ffcda170e2e6eeb6b15cf88bb8ade56a8eb48291f97ca5b9e1d2c45bf6ed9cb9e659b1be8e89ca2af0fea7c3b92aa18eb9d2c840af96bc8bf533a8a98586f034bc9d8382dc7297b982affc7ffcafbfaeb13fabb9a39bc15388b6e1abc6628cb297b5c94e869abf86ed3a9c97bfd0ef49a88e9b85d474afbc8797fb59b0e8fcccf57aa391b98fcb3bb096ae90c87d8dbc84d7d87a9ab8a299b339f4acb6b3ed6dfb92aab0cc4a8e88a9aad874f59983b6cc37e2a3; __utma=94650624.827593374.1534172700.1535852507.1535857189.3; __utmz=94650624.1535857189.3.3.utmcsr=baidu|utmccn=(organic)|utmcmd=organic; JSESSIONID-WYYY=kgbbgMKEcRf18SvvxZVqNTmWZD%2Fdn8BpA%2F7aMH7vv4mSpiDaE%5CfkC5xPu5hFv0nk5X7PpvlEJJ97%2BC3WyE5Qv50EW%2FdNPQQPenibqq%2F5IyHkuuMlCTkpkb7TRMl9oBEdFi68ktMI8m%2F5Ilyub4P204bpG0qBv4yx9vvw8CmCJ%2B9vCaSd%3A1535859527007; __utmb=94650624.7.10.1535857189',
'Referer':'https://music.163.com/song?id=1299557768',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
# 字符串拼接
url='http://music.163.com/api/v1/resource/comments/R_SO_4_1299557768?offset='+str(offset)+'&limit=20'
try:
time.sleep(2)
response=requests.get(url,headers=headers)
# 状态码判断
if response.status_code == 200:
return response.content
except Exception as e:
print('出错啦!')
return None

数据解析

其中提取到时间字段,无法直接转换为日期格式,会出现错误,根据测验需要缩小1000倍,得到浮点数,再进行日期格式进行转换。

[code]# 解析数据
def parse_json_data(contents):
if contents:
# 编码格式转换
contents=contents.decode('utf-8')
# api接口返回的数据是json格式,把json格式转换为字典结构,获取评论信息
comments=json.loads(contents)['comments']
for comment in comments:
content=comment['content']
nickname=comment['user']['nickname']
timeArray=time.localtime(comment['time']/1000)
style_time=time.strftime('%Y-%m-%d %H:%M:%S',timeArray)
yield{
'time':style_time,
'nickname':nickname,
'comment':content
}
# print(nickname+','+content+','+style_time)

数据保存

其中在写进csv文件后去用Excel去打开的话,会出现乱码,原因是因为csv文件是utf-8编码格式的,而默认打开csv文件的Excel是ANSI编码格式的,所以会乱码。然后在写进数据到文件时,指定编码格式为utf_8_sig就行,但是数字还是存在乱码,但对我们下面的操作没有影响。

[code]# csv保存数据
def save_csv_comments(messages,i):
# encoding=utf_8_sig只能转换中文乱码和字母乱码,不能支持数字的乱码
with open('comment_csv.csv','a',encoding='utf_8_sig',newline='')as f:
csvFile=csv.writer(f)
if i == 0:
csvFile.writerow(['评论时间','昵称','评论内容'])
csvdatas=[]
for message in messages:
csvdata=[]
csvdata.append(message['time'])
csvdata.append(message['nickname'])
csvdata.append(message['comment'].replace('\n',''))
csvdatas.append(csvdata)
csvFile.writerows(csvdatas)

文件读取

不能以二进制方式去读取文件,会出现错误,且必须知道评论内容在文件的哪一列且需要对对第一行中的评论内容的字段进行删除,所以选择了切片。

[code]# 读取csv文件的评论内容的一列
def read_csvFile(fileName):
with open(fileName,'r') as f:
# 因为此csv文件并非二进制文件, 只是一个文本文件
readerCSV=csv.reader(f)
comment_column=[row[2] for row in readerCSV]
return comment_column

词云生成

[code]# 词云生成
def make_word_cloud(text):
# 先把列表数据转换成字符串,再用jieba来分割字符串
comment_text=jieba.cut(''.join(text[1:]))
# list类型转换为str类型
comment_text=''.join(comment_text)
# 打开图片并转换为数组形式
animal=numpy.array(Image.open('timg_meitu_1.jpg'))
# 指定字体、背景颜色、宽高、词量、指定的背景图
wc=WordCloud(font_path='C:/Windows/Fonts/simsun.ttc',background_color="white",width=913,height=900, max_words=2000, mask=animal)
# 生成词云
wc.generate(comment_text)
#保存到本地
wc.to_file("animal.png")

实现结果

总结

  1. 网易云是个大厂,数据保密做的好,挺难抓取数据的。
  2. 需要更好的去解析网页,找好更好的解析方式。

链接:https://pan.baidu.com/s/1s68JG45BVlqJbxkahjEl0w 密码:2b4u

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: