抓取网易云音乐的评论数据并做可视化分析 - Python
网易云音乐火不火我不知道,但是网易云音乐的评论是真的火,不懂怎么会有这么多评论的人啊,想不通。之前看了很多文章是做网易云评论数据抓取并可视化的,今天我也来试着做个。随便找首歌。
爬虫部分
网易云音乐播放页面,https://music.163.com/#/song?id=1804320463,首先尝试了下requests直接抓取,发现返回的数据没有想要的内容。打开开发者工具,F12,查看了下源码,原来网易云音乐的数据都存储在iframe里,这就相当于给爬虫多做了扇门,所以想获取到想要的评论数据就必须进入到iframe里。
目标确定(要去iframe里获取数据),两种方式,第一种,通过selenium切入到iframe;第二种,通过评论内容在开发者工具里查找评论数据接口,然后将数据json化。
第一种方法:
1 """ 2 抓取网易云音乐的评论 3 """ 4 5 # 第一种方法,使用driver 6 import random 7 import time 8 from selenium import webdriver 9 from icecream import ic 10 import csv 11 from selenium.webdriver.common.by import By 12 13 def scroll_down_to_bottom(driver): 14 # 一个将网页下拉到底部的函数,尤其对懒加载好用,先传入驱动 15 # 思路是,针对懒加载的 16 # 1,先获取页面最大高度,通过js;并创建一个列表用于保存页面最大高度的值; 17 # 2,执行滚动条拖动操作到最底部,等待懒加载加载完成,加载完成后,滚动条的高度会增长; 18 # 3,将列表中的最后一个值,就是上一次页面高度和当前高度进行对比,如果相等,说明到了最底部,如果不等,表示懒加载出了新数据,那么继续上述步骤 19 browser_window_heights = [] # 创建列表,存储页面高度 20 # 获取第一次加载的页面高度并添加到列表 21 browser_window_heights.append(driver.execute_script("return document.body.scrollHeight;")) 22 # 开始循环 23 while True: 24 # 执行滚动操作 25 driver.execute_script("scroll(0, 10000);") 26 time.sleep(random.uniform(2, 5)) # 随机休眠2到5秒 27 # 获取执行滚动后的页面高度 28 check_now_height = driver.execute_script("return document.body.scrollHeight;") 29 # 将拖动滚动条后的高度与列表中的最后一次高度进行对比,如果相等,表明到了底部,如果不相等,继续循环 30 if check_now_height == browser_window_heights[-1]: 31 print('****当前高度与最后高度相等,已到底部!退出循环!****') 32 break 33 else: 34 # 如果不相等,就将滚动后的高度追加到列表末尾 35 browser_window_heights.append(check_now_height) 36 37 def save_to_csv(comment_user,comment_content, comment_time): 38 # # 保存到csv 39 # f = open('网易云音乐踏山河评论数据.csv', mode='a', encoding='utf-8-sig', newline='') 40 # csvWriter = csv.writer(f) # 写入器 41 # csvWriter.writerow(['评论人', '评论内容', '评论时间']) # 写入表头 42 # for data in datas: 43 # csvWriter.writerow(data) 44 # f.close() # 关闭文档 45 46 # 保存到csv也可以这样写 47 f = open('网易云音乐踏山河评论数据.csv', mode='a', encoding='utf-8-sig', newline='') 48 csvWriter = csv.DictWriter(f, fieldnames=[ 49 '评论人', 50 '评论内容', 51 '评论时间', 52 ]) 53 csvWriter.writeheader() # 写入头 54 ditdata = { 55 '评论人':comment_user, 56 '评论内容':comment_content, 57 '评论时间':comment_time, 58 } 59 csvWriter.writerow(ditdata) # 写入数据 60 f.close() 61 62 # 初始化浏览器驱动 63 driver = webdriver.Chrome() 64 # 利用驱动加载网页 65 driver.get('https://music.163.com/#/song?id=1804320463') # 这里以踏山河为例 66 # 利用selenium的隐式等待等待网页加载完成 67 driver.implicitly_wait(10) 68 # 定位到iframe 69 iframe = driver.find_element(By.ID, 'g_iframe') 70 # 切入iframe 71 driver.switch_to.frame(iframe) 72 # 利用滚动条下拉函数将页面拉到底部 73 scroll_down_to_bottom(driver=driver) 74 # 保存到csv 75 f = open('踏山河评论数据.csv', mode='a', encoding='utf-8-sig', newline='') 76 csv_writer = csv.writer(f) 77 csv_writer.writerow(['评论人','评论内容','评论时间']) # 写入头 78 79 # 查找评论信息 80 for page in range(1, 11): 81 print(f'------------------开始采集第{page}页数据!------------------') 82 comments = driver.find_elements(By.CLASS_NAME, 'itm') 83 print(len(comments)) 84 time.sleep(random.uniform(2, 5)) 85 datas = [] 86 print(f'正在采集第{page}页数据!') 87 for comment in comments: 88 comment_user = comment.find_element(By.XPATH, './/div[@class="cntwrap"]/div/div/a').text 89 comment_content = comment.find_element(By.CSS_SELECTOR, '.cntwrap div div').text # 需要处理 90 comment_content = comment_content.split(':')[-1].strip() 91 comment_time = comment.find_element(By.XPATH, './/div[@class="rp"]/div[contains(@class, "time")]').text 92 ic(comment_user, comment_content, comment_time) 93 # 调用写入器写入数据 94 csv_writer.writerow([comment_user, comment_content, comment_time]) 95 96 # 执行翻页 97 driver.find_element(By.XPATH, '//a[contains(@class, "zbtn znxt")]').click() 98 f.close() # 将文件关闭
第二种方法是通过开发者工具查找数据来源:数据来源是有的,但是它的参数进行了js加密。要解密他的js代码才能解析json数据。
数据处理
数据处理无非是用pandas对数据进行去重,删除空值处理。
1 import pandas as pd 2 3 # 读取数据 4 df = pd.read_csv('踏山河评论数据.csv') 5 # 去重复 6 df = df.drop_duplicates() 7 # 去空值处理 8 df = df.dropna() 9 # 抽样看看 10 print(df.sample(10))
数据可视化
做一个高频词的柱状图和饼图。
清洗完数据后提取出评论中的高频词。