python爬虫实战+数据分析+数据可视化(分析豆瓣 《飞驰人生》影评)

Iolanthe ·
更新时间:2024-11-10
· 970 次阅读

一、概要

     在学习了python爬虫(requests,bs4)以及numpy、pandas、matplotlib库之后,就想试个小项目磨磨刀。之前只会单方面的使用,比如爬取一个网站相关数据 或者 对已经给了的数据进行分析。这个项目将这几个部分串起来了。学过这几个库的人就知道,这个项目很简单嘛。确实不难,但是自己完整的做完还是会出很多意想不到的bug。另:如果有同学只想做数据分析和可视化展示,这也没问题。以下百度网盘链接也提供了已经使用爬虫获取的数据。

    环境:python(anaconda)

    源码:百度网盘链接:https://pan.baidu.com/s/101ck6wc_YyHuFLAZtLgLGA
               提取码:r1n1(包括源代码以及通过爬虫获取的影评内容)

              源码是ipynb文件,使用Jupyter Notebook打开

    忠告:朋友,可以拿我这个项目试试,今天刚出炉的,用的是,配了环境,然后安装下需要的包应就能跑的,要源码的复制上面百度网盘的链接就能获取。需要掌握的知识就是上面写的那几个python库。如有不佳,还请海涵。

    直接上图:这里只显示一部分对影评分析后得到的可视化图片。

    

 二、思路

    1、进入下面url,按F12打开 开发者模式,分析html代码,这里我主要获取了评论人用户名,评论时间,评论内容,评论评星,评论点赞数等,这几个信息。通过分析发现,下一页的链接是https://movie.douban.com/subject/30163509/reviews?start=20 ,没错,这样我们只需要一个for循环就能遍历完所有的评论了。大概3000多条评论左右,数量不算多,爬虫大概跑个4-5分钟就能爬下你需要的数据,爬下的数据存于一个csv文件就好(用excel可以打开)。

https://movie.douban.com/subject/30163509/reviews

    2、爬虫已经获取的数据,这里我们再使用numpy、pandas库对其进行数据分析,使用matplotlib来进行画图操作。就这些步骤,就这么简单。

三、具体实现(上代码)

tips:如果在实战这个项目的同学,建议下载好我分享的源码,以下内容只是将源码解释一遍

 1、爬取数据,存储至csv文件

以下代码是爬虫获取数据并且将其存入pacong.csv文件中,以上也说了,csv文件excel可以打开

其实运行以下代码爬到了大概3000多行数据后会报错。这不要紧,这个时候pacong.csv文件中已经将3000多条评论数据都存下来了。

这里使用csv库来存数据。其实也可以用mongodb数据库来存,但是配环境太烦了,这里就用了csv。这个csv库也简单,几行代码就解决了存储数据的问题。

import csv import numpy as np import requests from bs4 import BeautifulSoup import time def getHtmlText(url): headers = { 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0', 'Connection': 'close' } html = requests.get(url,headers = headers,verify=False).text return html def solveAndSave(url,writer): html = getHtmlText(url) soup = BeautifulSoup(html,'html.parser') review_list = soup.find('div','review-list') # print (review_list.div,'\n\n\n') # 这个方法遍及儿子节点,每次都会少第一个评论 for div in review_list.div.find_next_siblings()[0:-1]: # print ('\n\n\n',div) div = div('div')[0] # print (div) header = div('header')[0] # print (header) main_body = div('div')[0] # find header useful name = header('a')[1].string stars = header('span')[0].get('title') if len(header('span'))==1: time = 'no star' else: time = header('span')[1].string # find main body usefful title = main_body('h2')[0]('a')[0].string content = main_body.find('div','short-content').string action = main_body.find('div','action') userful_nums = str(action('a')[0]('span')[0].string).replace(' ','') useless_nums = str(action('a')[1]('span')[0].string.replace(' ','')) reply_nums = str(action('a')[2].string.replace(' ','')) data = [(name,stars,time,title,content,userful_nums,useless_nums,reply_nums)] writer.writerows(data) # 多行用writerows # csvfile.close() # print (name,stars,time,userful_nums,useless_nums,reply_nums) def main(): # write in csv csvfile = open('pacong.csv', 'w',newline='',encoding='utf-8') # 如果不指定newline='',有时则每写入一行将有一空行被写入 writer = csv.writer(csvfile) writer.writerow(['评论人姓名', '评价', '评论时间','评论标题','评论主体','赞成数','反对数','回复数']) # 写入一行用writerow for i in range(0,3980,20): time.sleep(0.5) url = 'https://movie.douban.com/subject/30163509/reviews?start='+str(i) solveAndSave(url,writer) csvfile.close() main()

大概csv内容的样子如下:

2、分析数据并画图

这里使用csv文件中评论标题这一列,做个词云来玩玩。词云里面可以不加 ’mask=background_image这个参数,这个主要控制词云生成的形状。当然你也就不用导入cv2的库了

这里上代码:

import pandas as pd import matplotlib.pyplot as plt import numpy as np from wordcloud import WordCloud import jieba import cv2 as cv # 读入图片背景 # 对于中文词云首先使用jieba来中文分词,然后还要记得指定font_path设置字体识别 # 想要的话还能设置词云的背景图片 background_image = cv.imread('../image/ciyun.jpg') # 不设置background_image可以不加这行,得到的词云就是矩形了 # with open('pacong.csv','r',encoding='utf-8') as f: # text = f.read() # print (text) yingping = pd.read_csv('pacong.csv') all_content = '' for i in range(0,len(yingping['评论标题'])): all_content= all_content+yingping['评论标题'][i] cut_text = " ".join(jieba.cut(all_content)) # print (cut_text) # print (all_content) # yingping.head() wordcloud = WordCloud(font_path="C:/Windows/Fonts/simfang.ttf",mask=background_image,background_color='white').generate(cut_text) plt.figure(figsize=(10,10)) plt.imshow(wordcloud,interpolation="bilinear") plt.axis("off") plt.show()

效果:

接下来,开始对数据坐下子预处理咯,你看下面代码,就是把赞成数,反对数,回复数这几列处理了下。我们爬下来的csv中,这几列有一些换行和文字,用string的repalce方法替换一下就行。还要将评价的文字转化为评论得分,
这个操作很简单对不对,但是可以说的高大上点,就是做数据挖掘(就是把数据的文本信息提取为我们可分析的数据类型)

# help(yingping.last) print (yingping.head()) def prepressingData(data1): data = data1.copy() zancheng = data['赞成数'] fandui = data['反对数'] huifu = data['回复数'] pingjia = data['评价'] star = [] for i in range(0,len(zancheng)): zancheng[i] = zancheng[i].replace('\n','') fandui[i] = fandui[i].replace('\n','') huifu[i] = huifu[i].replace('回应',' ') if pingjia[i]=='力荐': star.append(5) elif pingjia[i]=='推荐': star.append(4) elif pingjia[i]=='还行': star.append(3) elif pingjia[i]=='较差': star.append(2) elif pingjia[i]=='很差': star.append(1) else: star.append(0) data['评价得分'] = pd.Series(star) data = data.drop(axis=1,columns=['评论主体']) # 删除列,后要赋值过去才算成功 return data yingping = prepressingData(yingping)

将我们上面通过评价列得到的评价得分列做个直方图,

yingping.head(50) # yingping['赞成数'][3377] yingping.isnull().any() # 画图开始 plt.rcParams['font.sans-serif']=['SimHei'] plt.figure(figsize=(10,8)) plt.hist(yingping['评价得分'],bins=20) plt.xlabel('星级(0表示没有评级)',size=14) plt.ylabel('人数',size=14) plt.show()

效果:通过结果可以看出评分4-5颗星占大多数,应该属于一个好评居多的电影。(没看过飞驰人生的人可以康康,毕竟自己分析的这个电影还不错撒)

   然后呢,接下来的代码我就不具体解释了,直接上代码和效果,毕竟大家还有度娘

将以下几种类型转化为数字类型,有NAN(缺失值)的使用fillna进行填充

yingping.head() def cvtInt(data1): data = data1.copy() data['赞成数'] = pd.to_numeric(yingping['赞成数'],errors='ignore') data['赞成数'] = data['赞成数'].fillna(0) data['反对数'] = pd.to_numeric(yingping['反对数'],errors='ignore') data['反对数'] = data['反对数'].fillna(0) data['回复数'] = pd.to_numeric(yingping['回复数'],errors='ignore') return data yingping = cvtInt(yingping) # yingping.sort_values(by=['赞成数'],ascending=False) # yingping.sort_values(by=['回复数'],ascending=False) # yingping.isnull().any() import numpy as np # pd.to_numeric(yingping['赞成数'],errors='ignore') yingping['评论时间'] def dropUselessTime(data): data1 = data.copy() index = data1[data1['评论时间']=='no star'].index data1 = data1.drop(axis=0,index=index) return data1 yingping = dropUselessTime(yingping) yingping.index = yingping['评论时间'] yingping

效果:

 接下来:

# help(yingping.drop) # yingping['year'] = pd.to_datetime(yingping['评论时间']).dt.year yingping['month'] = pd.to_datetime(yingping['评论时间']).dt.month yingping['hour'] = pd.to_datetime(yingping['评论时间']).dt.hour def plotTimeWithData(data): data1 = data.copy() cur = data1.groupby('hour').count() plt.figure(figsize=(10,6)) plt.plot(cur.index,cur['month']) plt.xlabel('时间/hour',size=16) plt.ylabel('评论数量',size=16) plt.title('评论数量随时间段的变化',size=16) xticks=list(range(0,len(cur.index))) # 这里设置的是x轴点的位置 plt.xticks(xticks) plt.show() cur = data1.groupby('hour').mean() plt.figure(figsize=(10,6)) plt.plot(cur.index,cur['评价得分']) plt.xlabel('时间/hour',size=16) plt.ylabel('评论分均值',size=16) plt.title('评论均值随时间段的变化',size=16) xticks=list(range(0,len(cur.index))) # 这里设置的是x轴点的位置 plt.xticks(xticks) plt.show() plotTimeWithData(yingping)

效果:

 

     分析这两图发现,从凌晨4点-23点评论数量是不断增多的,说明大多数人喜欢在晚上看这部电影并且评论。然后咧,发现在凌晨三点评分的均值相当的低啊,说明在3点中的时候,大家心情都不太好的亚子,所以这也告诉我们,不要去惹经常熬夜的人,他们的心情可不好哦;这六点钟早起的人心情就不错,评分均值达到一天的最高点

四、总结

    当然三千组数据可能还是有点少,但是我们就是学习嘛,能学到东西就好了。还有其实还能通过分析数据画很多有意义的图,有兴趣的同学可以学习以下seaborn库(matplotlib库封装的基础上的库),可以画出能多精美的图哟。可以参考我的另外一篇博客https://blog.csdn.net/weixin_41466575/article/details/104343245

   有问题的伙伴可以在评论区中留言,我会及时回复大家的!!!

   http://liuyishou.site  这是我个人开发的博客网站哦,欢迎大家来参观。


作者:刘一手emm



人生 Python爬虫实战 实战 数据 数据分析 数据可视化 豆瓣 可视化 python爬虫 Python

需要 登录 后方可回复, 如果你还没有账号请 注册新账号