飞道的博客

抓取了《大秦赋》所有数据,我发现了这些秘密

283人阅读  评论(0)

​​​​​推荐一门我学过的爬虫课程,课程按照网络请求→数据分析→数据存储这几个步骤进行讲解,带你完整的掌握每个技术。从基础爬虫到商业化应用爬虫,非常全面。

点击查看课程详情→《150讲轻松搞定Python爬虫》

作者:黄勇,网易、360、华为特约Python讲师

前言

最近大火的电视剧《大秦赋》,给朋友圈的小伙伴都拉回到那个风云激荡的春秋战国时期,大家都在热情的讨论着大秦一统,秦始皇嬴政、商人吕不韦的那些尔虞我诈、恩怨情仇。那到底小伙伴们都在讨论什么,对历史人物有什么看法,对《大秦赋》这部电视剧剧情和角色有什么点评?于是我用Python爬取了《大秦赋》下所有的评论数据,进行了一波分析。

 

1、 数据抓取

 

巧妇难为无米之炊,我们首先要做的第一步是想办法抓取到评论数据。这里我们抓取的是豆瓣网上关于《大秦赋》的所有评论数据,选择豆瓣网原因很简单,首先是数据比较齐全,其次反爬难度并不大。

其次来说下技术栈,用的是Scrapy+JSON的方式实现的。Scrapy框架有脚手架功能,帮我们实现了一个爬虫大部分的功能,我们只要专心于数据解析和存储即可,也是我做爬虫的首选框架。

第一步是通过`Scrapy`命令创建一个项目和爬虫:


  
  1. scrapy startproject daqinfu
  2. scrapy genspider daqinfu "douban.com"

在开始编写爬虫之前,先来看下请求的url,这里我们找到《大秦赋》的评论链接是:

https://movie.douban.com/subject/26413293/comments?start=60&limit=20&status=P&sort=time

其中start是获取评论的起始位置,limit代表获取多少条评论数据。

 

在获取完一页数据后,只要再获取下一页的url,然后重复发送请求即可。

了解以上两点后,就可以开始写代码了。当然前提是要对数据的提取比较熟悉,数据提取常用的有BeautifulSoup/Xpath/正则等方式,这里我们用性能和可阅读性都比较好的提取规则——xpath来进行解析。爬虫部分代码如下:


  
  1. # -*- coding: utf-8 -*-
  2. import re
  3. from ..items import QinItem
  4. class QinSpider(scrapy.Spider):
  5. name = 'qin'
  6. allowed_domains = [ 'douban.com']
  7. start_urls = [ 'https://movie.douban.com/subject/26413293/comments?start=0&limit=20']
  8. domain = "https://movie.douban.com/subject/26413293/comments"
  9. def parse(self, response):
  10. comment_items = response.xpath( "//div[@id='comments']/div[contains(@class,'comment-item')]")
  11. for comment_item in comment_items:
  12. pub_time = comment_item.xpath( ".//span[contains(@class,'comment-time')]/@title").extract_first()
  13. rating_classes = comment_item.xpath( ".//span[contains(@class,'rating')]/@class").extract_first()
  14. rating = re.search( r'allstar(\d)0 rating',rating_classes).group( 1)
  15. content = comment_item.xpath( ".//p[contains(@class,'comment-content')]/span/text()").extract_first()
  16. item = QinItem(pub_time=pub_time,rating=rating,content=content)
  17. yield item
  18. query = response.xpath( "//div[@id='paginator']/a[@class='next']/@href").extract_first()
  19. if query:
  20. yield scrapy.Request(url=self.domain+query,callback=self.parse)
  21. print( "="* 40)
  22. print(response.url,query)
  23. print( "=" * 40)

爬取规则写好后,会构建一个item对象,这个item对象在yield过去后会发送给pipeline,然后我们在pipeline中把他保存到起来即可。相关代码如下:


  
  1. import json
  2. def __init__(self):
  3. self.fp = open( "comments.json", 'w', encoding= 'utf-8')
  4. def process_item(self, item, spider):
  5. self.fp.write(json.dumps(dict(item))+ "\n")
  6. return item
  7. def close_spider(self,spider):
  8. self.fp.close()

这样,我们通过在命令行输入:scrapy crawl qin,即可运行我们的代码了。

​​​​​推荐一门我学过的爬虫课程,课程按照网络请求→数据分析→数据存储这几个步骤进行讲解,带你完整的掌握每个技术。从基础爬虫到商业化应用爬虫,非常全面。

点击查看课程详情→《150讲轻松搞定Python爬虫》

 2、数据分析:

抓取了评论数据后,我们开始来进行一些分析。

首先说一下技术栈,这里我们用的是Anaconda中的Jupyter Notebook来做,然后用到了Pandas+Seaborn做数据处理和可视化。

首先将之前保存的JSON格式数据,处理成DataFrame对象。相关代码如下:


  
  1. items = []
  2. with open( "comments.json", "r") as fp:
  3. for line in fp:
  4. comment = json.loads(line)
  5. items.append( comment)

  
  1. item_list = [[item['pub_time'],item['rating'],item['content']] for item in items]
  2. comment_df = pd.DataFrame(item_list,columns=[ 'pub_time', 'rating', 'content'])
  3. comment_df[ 'pub_time'] = pd.to_datetime(comment_df[ 'pub_time'])
  4. comment_df.head()

数据处理好以后,就可以进行分析了。这里我们从几个维度来分析,第一个是评论时间,第二个是评分,第三个是评论内容(您也可以自己再多从几个维度来分析)。

 

2.1. 时间分析

 

时间我们分成两点来做,分别是发布日期、发布时间。分析发布日期我们能知道评论的走势,分析发布时间我们可以知道《大秦赋》在什么时间点播放量是最高的。

先来看看发布时间,《大秦赋》是在12月1日首播,到目前为止已经半个月了。我们来看看这半个月时间的播放情况。以下是分析代码:


  
  1. # 分析评论日期
  2. from matplotlib import dates

  
  1. plt.figure(figsize=( 10, 5))

  
  1. # 2. 添加一个新的pub_date
  2. comment_df[ 'pub_date'] = comment_df[ 'pub_time'].dt.date
  3. # # 3. 根据日期分组绘图
  4. comment_date_df = comment_df.groupby([ 'pub_date']).count()
  5. ax = sns.lineplot( x=comment_date_df.index, y=comment_date_df.content,marker= 'o')
  6. # 设置显示所有时间
  7. ax.set(xticks=comment_date_df.index)
  8. # 设置x轴旋转
  9. _ = ax.set_xticklabels(comment_date_df.index,rotation= 45)
  10. # 设置x轴格式
  11. ax.xaxis.set_major_formatter(dates.DateFormatter( "%m-%d"))
  12. ax.set_xlabel( "发布日期")
  13. ax.set_ylabel( "评论数量")

 

可以看到评论数量在12月4日之前都是一直处于上升趋势,在12月4日达到顶峰。前面4天属于观众期待期,所以评论量会越来越多,但是在12月4日后出现断崖式下降,说明本剧可能不是很受大家喜爱。

再来看下评论的时间,看看大家一般在几点刷剧。这里小编从0点到24点,2个小时为一个时间段统计评论数量。相关代码如下:


  
  1. # 分析评论时间
  2. time_range = [ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]
  3. comment_time_df = comment_df['pub_time'].dt.hour
  4. time_range_counts = pd.cut(comment_time_df,bins=time_range,include_lowest=True,right=False).value_counts()
  5. ax = time_range_counts.plot(kind="bar")
  6. _ = ax.set_xticklabels(labels=time_range_counts.index,rotation=45)
  7. ax.set_xlabel("发布时间")
  8. ax.set_ylabel("发布数量")

 

可以看到在晚上8点到10点是评论量最多的,也正是电视剧播出时间段。紧接着是22-24,以及0-2点,有一部分晚上很晚才下班的小伙伴,可能会在这段时间追剧。然后又是上午10-12,以及14,16点,这段时间课时工作的最佳时间呀,怎么会用来追剧呢。说明有相当一部分小伙伴,平时工作在摸鱼呀,哈哈。

 

2.2. 评分分析

 

想要知道一部剧好不好,最直接的就是看观众给的评分,通过以下代码分析:

其中1,2分的最多。说明《大秦赋》真的没有被观众所认可呀。 

2.3. 分析人物评分

 

剧中演员的演技,以及故事情节,会对剧的评分产生较大影响,那么《大秦赋》中各个角色的演技,以及这个角色所产生的故事情节如何,我们接下来做一个简单分析。

这里我们的算法比较简单(不是很严谨,但是也能说明问题)。举个例子,观众给了1星,然后这个评论内容中出现了几次”秦始皇“,说明观众对”秦始皇“这个角色是比较反感的。这里我们对内容进行分词,然后提取”秦始皇“,”吕不韦“,”赵姬“,”嫪毐“,”李斯“等人进行分析。代码如下:


  
  1. # 电视剧人物的评分
  2. import jieba
  3. roles = { '嬴政': 0, '秦始皇': 0, '张鲁一': 0, '吕不韦': 0, '段奕宏': 0, '李斯': 0, '嫪毐': 0, "赵姬": 0, "朱珠": 0}
  4. role_names = list(roles.keys())
  5. for name in role_names:
  6. jieba.add_word(name)
  7. for row in comment_df.index:
  8. rating = comment_df.loc[row, 'rating']
  9. if rating:
  10. content = comment_df.loc[row, "content"]
  11. words = list(jieba.cut(content, cut_all= False))
  12. names = set(role_names).intersection(set(words))
  13. for name in names:
  14. roles[name] += int(rating)
  15. roles[ '嬴政'] += roles[ '嬴政'] + roles[ '秦始皇'] + roles[ '张鲁一']
  16. roles[ '吕不韦'] += roles[ '吕不韦'] + roles[ '段奕宏']
  17. roles[ '李斯'] += roles[ '李斯']
  18. roles[ '赵姬'] += roles[ '赵姬'] + roles[ '朱珠']

  
  1. roles .pop( "秦始皇")
  2. roles .pop( "张鲁一")
  3. roles .pop( "段奕宏")
  4. roles .pop( "朱珠")

  
  1. role_df = pd.DataFrame( list(roles.values()),index= list(roles.keys()),columns=[ '得分'])
  2. role_df.sort_values( '得分',inplace= True,ascending= False)
  3. role_df.plot(kind= 'bar')

嬴政是最受观众关注和喜爱的,也符合一统天下得思想。虽然出镜很多的嫪毐,但是评分却很低。

只要你爬虫玩得溜,抓到更多的数据,还有更多有趣好玩的细节等着你来探索!

​​​​​推荐一门我学过的爬虫课程,课程按照网络请求→数据分析→数据存储这几个步骤进行讲解,带你完整的掌握每个技术。从基础爬虫到商业化应用爬虫,非常全面。

点击查看课程详情→《150讲轻松搞定Python爬虫》

 


转载:https://blog.csdn.net/csdngkk/article/details/114288145
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场