Python爬虫与数据分析

  1. 目的
    爬取网易云音乐歌曲热评,分析热评特征。
  2. 思路
    (1)爬取华语歌单中所有歌单url
    (2)从每篇歌单地址中爬取每首歌的url
    (3)从每首歌的首页爬取热评
  3. 代码

(1) 爬取华语歌单中所有歌单url,从歌单url获取歌单中每首歌的歌名和id,并保存到文件music_163_02.csv。

import logging
import requests
from pyquery import PyQuery as pq
import pandas as pd
import random
import time# headers需要填上,否则无法正常爬取
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'}
# 设置日志的格式、输出级别
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s: %(message)s')def scrape_index(url):response = requests.get(url,headers = headers )logging.info('scrape index %s...',url)   #不需要再url前加%,而是,try:if response.status_code == 200:      return parse_index(response.text)      # 传到parse_index 方法中获取歌单url列表else :logging.error('invaild status is %s while scraping url %s', response.status_code, url)except Exception:logging.error('error occurred while scraping %s', url, exc_info=True)  # exc_info=True:会将异常异常信息添加到日志消息中 def parse_index(html):doc = pq(html)    # 用pyquery进行解析             a = doc('#m-pl-container .dec .s-fc0')   # #对应div .对应classa1 = a.items()  # 对于返回值是多个元素,然后对每个元素做处理,需要调用items方法,返回的generator类型,可以通过for 循环去取值return a1def scrape_detail(url):response = requests.get(url,headers = headers )logging.info('scraping detail %s...',url)try:if response.status_code == 200:logging.info('detail url is succeed ')return parse_detail(response.json())    # API获取的内容返回的是json格式else:logging.error('invaild status is %s while scraping url %s', response.status_code, url)except Exception:logging.error('error occurred while scraping %s', url, exc_info=True)'''
热评获取API:http://music.163.com/api/v1/resource/comments/R_SO_4_{歌曲ID}?limit=20&offset=0
所以获取歌曲的ID就可以得到热评
'''
def parse_detail(html):list_02 = []jobs = html['result']['tracks']for j in jobs:dic ={}dic['name'] = j['name'] # 创建 字典dic['id'] = j['id']list_02.append(dic)    return list_02 def get_list():list_01 = []url = 'https://music.163.com/discover/playlist/?order=hot&cat=%E5%8D%8E%E8%AF%AD&limit=35&offset={page}'for page in range(0,35,35):    # 跑一页试试,如果跑全部,改为 range(0,1295,35)url1 = url.format(page = page)list = []for i in scrape_index(url1):  #  generator 遍历之后的i的类型仍然是qyquery类型i_url = i.attr('href')     #  attr 方法来获取属性'''获取歌单和评论均用了网易云音乐get请求的API,快速高效!网易云歌单APIhttps://music.163.com/api/playlist/detail?id={歌单ID}热评获取APIhttp://music.163.com/api/v1/resource/comments/R_SO_4_{歌曲ID}?limit=20&offset=0'''detail_url = f'https://music.163.com/api{i_url.replace("?","/detail?")}'    #获取的url还需要替换一下符合API要求的格式list.append(detail_url) list_01.extend(list)    # extend 对列表合并          time.sleep(5+random.random())  # 文明爬虫return list_01df = pd.DataFrame(columns = ('name','id'))def save_date(list):df1 = pd.DataFrame(list)df2 = pd.concat([df, df1])df3 = df2.drop_duplicates(subset=None, keep='first',inplace = False) df3.to_csv('G:/work/01_project/05_Data/music_163_02.csv',index_label="index_label", encoding='utf-8-sig')  # index_label索引列的列标签def main():detail_list = []url_01 = get_list()for l in url_01:logging.info('detail url is %s',l)detail_list_part = scrape_detail(l)  detail_list.extend(detail_list_part)   # 列表合并,得到最后的完整歌单信息列表time.sleep(5+random.random()) save_date(detail_list)     if __name__ == '__main__':main()

(2)获取每首歌的url,从首页得到热评信息

import pandas as pd
import requests
import logging
import time
import randomheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36'}
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s: %(message)s')def scrape_comment(url, name):logging.info('scraping comments %s',url)try:response = requests.get(url, headers = headers)if response.status_code == 200:return parse_comment(response.json(), name )    # 网易云热评API返回的是json格式else :logging.error('invaild status_code %s while scraping %s',response.status_code, url)except Exception:logging.error('can not scraping %s', url)def parse_comment(html, name ):data = []jobs =  html['hotComments']for job in jobs:dic = {}dic['nickname'] = job['user']['nickname']dic['userid'] = job['user']['userId']dic['content'] = job['content'].replace('\n', '')     #  对换行符进行替换     dic['likecount'] = job['likedCount']dic['time'] = stampToTime(job['time'])   # 时间戳的转换dic['name'] = namedata.append(dic)return data   def stampToTime(stamp):'''获得是13位的时间戳,需要转化成时间字符串将ms(毫秒)转成s(秒)  stamp/1000将10位的符合python的时间戳转化成时间元组,localtime():北京时间将时间元组用strftime转化成时间字符串'''timeStamp = float(stamp/1000)   timeArray = time.localtime(timeStamp)date = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)return datedef main():df = pd.read_csv('G:/work/01_project/05_Data/music_163_02.csv',header = 0)   # 对上个保存的歌曲的ID的csv的内容提取,header= 0:第一行作为columndata_comment = []for index,row in df.iterrows():    # 数据框中的行 进行迭代的一个生成器,它返回每行的索引及一个包含行本身的对象。name = row['name']url = f'http://music.163.com/api/v1/resource/comments/R_SO_4_{row["id"]}?limit=20&offset=0'   # 本文只爬取首页(第一页)的热评data1 = scrape_comment(url, name)   data_comment.extend(data1)    df1 = pd.DataFrame(data_comment)df1.to_csv('G:/work/01_project/05_Data/hotComments_06p.csv',encoding = 'utf-8-sig')    # 是utf-8-sig 而不是utf-8logging.info('scraping id %s',index)time.sleep(random.random())   # 文明爬虫if __name__ == '__main__':main()
  1. 代码思路总结
    爬虫实际是模拟人对网页信息进行获取,而代码则替代人工,快速且可暴力循环的,解析并爬取互联网的大量信息。(个人简单理解)

    从思路中分析,提出以下问题:
    

    (1)如何爬取华语歌单中所有歌单url,并从每篇歌单地址中爬取每首歌的url?(代码块1实现,Python包是工具包)
    步骤如下:
    a、进入华语歌单url,循环获取每一页歌单里的每个歌单url ,歌单url用pyquery进行解析html进行获取,获取的url需要替换成符合API要求的格式,将每一页的API列表进行合并。
    b、从歌单API列表中用requests得到响应的json,解析json获取想要得到的所有歌曲key和value,将这些key和value放入字典,将这些字典放入列表中,得到的列表是一个歌单里的歌曲列表,将每个歌单的歌曲列表合并。
    c、得到歌曲列表的歌名和url的id值,保存数据到文件music_163_02.csv。

(2)如何从每首歌的首页爬取热评?(代码块2实现,Python包是工具包)
步骤如下:
a、读取文件music_163_02.csv获取歌曲id和名字,热评API中加入歌曲id,只爬取第一页的热评。用requests得到响应的json,从json中获取具体的评论,评论列表合并。

  1. 数据清洗、数据获取与数据分析
    (1)数据清洗与具体数据获取
import matplotlib.pyplot as plt
import pandas as pd
import jieba
import jieba.analyse
import numpy as np
from PIL import Image
from wordcloud import WordCloud'''
发现也是因为csv文件中单个item内有\r,即回车符
解决方法:lineterminator=”\n”:让\n作为换行符即可
'''
df3 = pd.read_csv('G:/work/01_project/05_Data/hotComments_06p.csv',index_col = 0,lineterminator='\n')# 用strip()方法去除开头或则结尾的空格
df3['content1'] = df3['content'].apply(lambda x:x.strip())# 有些句子中有\r,因为我们以\n作为换行符,所以这些\r不属于文本,需要去掉
df3['content1'] = df3['content'].apply(lambda x:x.replace('\r', ''))
df4 = df3.drop(['content'],axis=1)
df4.rename(columns = {'content1':'content'},inplace = True)
df4['name1'] = df4['name\r'].apply(lambda x:x.replace('\r', ''))
df5 = df4.drop(['name\r'], axis=1)
df5.rename(columns = {'name1':'name'}, inplace=True)
df5# 对点赞数排序
df6 = df5.sort_values(by = 'likecount', ascending=False)
#df6.head(10)['content']
df6.head(10).to_csv('G:/work/01_project/05_Data/strat_TOP10.csv', index=False, encoding = 'utf-8-sig')
df6

# 对重复的句子次数排序
df7 = df5.groupby('content').size().sort_values(ascending=False).reset_index(name='count')
df7

(2)数据分析

#热评最多的ID都有那些特征
df8 = df5.groupby('userid').count().sort_values(by='content',ascending=False)
df8
# 热评最多的Id 是 626970848
from matplotlib.font_manager import FontProperties
font_set = FontProperties(fname=r"c:\windows\fonts\simsun.ttc", size=15)df9 = df5[df5['userid'] == 626970848]plt.hist(df9['likecount'], bins = 200, density = True )
plt.xlim((0,70000))
plt.title('用户的点赞分布', fontproperties=font_set)
plt.show()df9


df10 = df9['content'].map(len)      # map函数进行求取每一单元格个长度
plt.hist(df10, bins = 20, density = True)
plt.title('626970848用户的评论长度分布', fontproperties=font_set)
plt.show()df10

热评最多的用户点赞数集中分布在10000以下,几千几百的最多,侧面说明了这些歌曲是比较小众的,可能在新歌区广撒网评论。评论长度集中在60字以下,侧面说明短评获取关注度更多。

热评的频次较多的词语有哪些?

'''jieba库中基于 TextRank 算法的关键词抽取详情见官方文档:https://github.com/fxsjy/jieba
'''
segments = []
for index,row in df4.iterrows():  content = row[5]words = jieba.analyse.textrank(content,topK=3, withWeight=False,allowPOS=('ns', 'n', 'vn', 'v'))for w in words:                                    # 对分词好后的words进行提取,并且关联一个1,方便进行计数segments.append({'word':w,'counts':1})
df_w = pd.DataFrame(segments)df_w.to_csv('G:/work/01_project/05_Data/jieba_01.csv',index = False,encoding = 'utf-8-sig')
from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator  text = ' '.join(df_w['word'])mask_cir = np.array(Image.open('G:/work/01_project/05_Data/2222.png')) wordc =WordCloud(background_color='white',mask = mask_cir,font_path = 'G:/work/01_project/05_Data/simhei.ttf',    # 中文显示的方法,baidu载一个SimHei.ttf字体包即可让云词显示中文max_words=1000).generate(text)
plt.imshow(wordc)
plt.axis('off')plt.show()


将所有热评绘制成词云,发现“喜欢”与“首歌”这两个词汇被最多提及。还有其他“感觉”、“大哭”、“女孩”等,也许大部分人都经历过的两件事,就是年少懵懂的倾慕与深夜崩溃的瞬间。

本文学习知乎链接实战(其代码有部分缺少以及错误):https://zhuanlan.zhihu.com/p/143188410?utm_source=wechat_session

Python爬虫与数据分析相关推荐

  1. 【爬虫+数据可视化毕业设计:英雄联盟数据爬取及可视化分析,python爬虫可视化/数据分析/大数据/大数据屏/数据挖掘/数据爬取,程序开发-哔哩哔哩】

    [爬虫+数据可视化毕业设计:英雄联盟数据爬取及可视化分析,python爬虫可视化/数据分析/大数据/大数据屏/数据挖掘/数据爬取,程序开发-哔哩哔哩] https://b23.tv/TIoy6hj

  2. Python 爬虫和数据分析实战

    课程介绍 本课程以一个小项目带你快速上手 Python 爬虫和数据分析,主要分 3 部分: 第 1 部分是 Python 爬虫,主要使用 Urllib 3 和 BeautifulSoup 抓取天猫商城 ...

  3. 毕业设计 python爬虫基础+数据分析

    学习目标: 完成内容:python爬虫基础+数据分析(3.23-4.10) 6天学会数据可视化内容 4月10号完成毕设论文 [如果没有被免毕业设计的话] 学习内容: 软件安装 安装python3.10 ...

  4. 【【数据可视化毕业设计:差旅数据可视化分析,python爬虫可视化/数据分析/大数据/大数据屏/数据挖掘/数据爬取,程序开发-哔哩哔哩】-哔哩哔哩】 https://b23.tv/iTt30QG

    [[数据可视化毕业设计:差旅数据可视化分析,python爬虫可视化/数据分析/大数据/大数据屏/数据挖掘/数据爬取,程序开发-哔哩哔哩]-哔哩哔哩] https://b23.tv/iTt30QG ht ...

  5. Python爬虫、数据分析、可视化学习笔记(一、梦开始的地方)

    系列文章持续更新中...... 文章目录 一.工具及环境配置 1.Python3.8(官网下载) 2.Pycharm(官网下载) 3.Anaconda(官网下载) 4.环境配置(传送门,感谢前人栽树) ...

  6. 6张脑图系统讲透python爬虫和数据分析、数据挖掘

    1.python爬虫:比较详细介绍了爬虫所需要具备的库.工具.爬虫基础知识 2.python爬虫流程 3.python数据分析简介 4.python数据预处理方法 5.python数据挖掘基础 6.p ...

  7. python爬虫和数据分析电脑推荐_大数据分析必备的5款Python爬虫库

    在数据科学或人工智能领域,除了算法之外,最重要的应该是数据了.甚至可以说一个模型到最后决定其准确度的往往不是算法而是数据.在现实中,缺少足够的数据成了数据分析师获得优秀模型的主要阻碍.可喜的是,现在网 ...

  8. 基于 Python 爬虫+简单数据分析的课程设计(附PPT)

    按照课程设计要求,要用python做一个关于数据分析的小项目,在这里我们选的是爬取豆瓣图书TOP250,其中用到一些常用的数据处理及可视化方法,比如Echarts.Flask等! PPT部分截图: 报 ...

  9. 全网最全python爬虫+数据分析资源整理

    4.29(第二天) 开篇词 你为什么需要数据分析能力? 第一模块:数据分析基础篇 (16讲) 01丨数据分析全景图及修炼指南 02丨学习数据挖掘的最佳路径是什么? 03丨Python基础语法:开始你的 ...

最新文章

  1. 高性能 Java 应用层网关设计实践
  2. qt mysql显示文件名字_【实例】Qt获取文件属性
  3. 让Windows 2000/XP系统自动登陆
  4. 深入理解Java虚拟机--中
  5. 组合数学:容斥原理(HDU1976)
  6. html5画图论文结束语,基于HTML5 Canvas的画图板的设计与实现.doc
  7. Arduino十大滤波算法程序大全(精编无错版)
  8. 人工神经网络之Python 实战
  9. .net core 图片合并,图片水印,等比例缩小,SixLabors.ImageSharp
  10. 利用函数imnoise2处理噪声污染和spfilt处理滤波器
  11. Real Estate Photography: Exterior at Twilight 房地产摄影:暮光之城 Lynda课程中文字幕
  12. Android源码在线查看工具
  13. linux系统编译Q,Linux下安装qBittorrent,开启24小时挂机BT下载
  14. java中CheckException和UnCheckException的区别
  15. python古诗词生成_Python一日一练02----诗词生成器
  16. 后缀为.epub的是什么格式的文件
  17. b区机械考研哪些院校比较好考?
  18. 利用ajax从jsp中返回的字符串时出现回车符号解决办法
  19. 电商API店铺订单接口(代码对接教程)
  20. 《我是一只IT小小鸟》连载五

热门文章

  1. 2020年c语言二级考试题库免费,2020年国家级计算机等级考试二级C语言考试试题库.pdf...
  2. 如何使用蓝牙实现OTA固件升级
  3. Java打印int类型二进制
  4. 一篇文章让你搞懂Java中的静态代理和动态代理
  5. 基于jQuery的2048游戏
  6. 木桶原则(计算机,新木桶原则
  7. keil编程时 error: #65: expected a “;“ 的解决办法
  8. 使用Origin进行非线性高斯拟合
  9. spring之所以不用new对象!
  10. A10-7860K试装DSM