天天看點

python爬蟲實戰---網易雲音樂評論抓取

本文主要是提取網易雲音樂中歌曲的評論時間、評論者昵稱、評論内容,并把資料寫進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。

python爬蟲實戰---網易雲音樂評論抓取

導入包 

import requests---網頁請求

import json---格式轉換

import csv---資料儲存

import time---延時操作

import jieba---分詞處理

import numpy---圖檔的轉換

from PIL import Image---圖檔處理

from wordcloud import WordCloud---詞雲制作

抓取過程

網頁請求

"""
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倍,得到浮點數,再進行日期格式進行轉換。

# 解析資料
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就行,但是數字還是存在亂碼,但對我們下面的操作沒有影響。

# 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)
           

檔案讀取

不能以二進制方式去讀取檔案,會出現錯誤,且必須知道評論内容在檔案的哪一列且需要對對第一行中的評論内容的字段進行删除,是以選擇了切片。

# 讀取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
           

詞雲生成

# 詞雲生成
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")
           

實作結果

python爬蟲實戰---網易雲音樂評論抓取

總結

  1. 網易雲是個大廠,資料保密做的好,挺難抓取資料的。
  2. 需要更好的去解析網頁,找好更好的解析方式。

連結:https://pan.baidu.com/s/1s68JG45BVlqJbxkahjEl0w 密碼:2b4u