zoukankan      html  css  js  c++  java
  • Python 爬取猫眼电影《无名之辈》并对其进行数据分析

    前言

    文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

    作者: 罗昭成

    PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

    http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef

    获取猫眼接口数据

    作为一个长期宅在家的程序员,对各种抓包简直是信手拈来。在 Chrome 中查看原代码的模式,可以很清晰地看到接口,接口地址即为:

    http://m.maoyan.com/mmdb/comments/movie/1208282.json?_v_=yes&offset=15

    在 Python 中,我们可以很方便地使用 request 来发送网络请求,进而拿到返回结果:

    1 def getMoveinfo(url):
    2     session = requests.Session()
    3     headers = {
    4         "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X)"
    5     }
    6     response = session.get(url, headers=headers)
    7     if response.status_code == 200:
    8         return response.text
    9     return None

    根据上面的请求,我们能拿到此接口的返回数据,数据内容有很多信息,但有很多信息是我们并不需要的,先来总体看看返回的数据:

     1 {
     2     "cmts":[
     3         {
     4             "approve":0,
     5             "approved":false,
     6             "assistAwardInfo":{
     7                 "avatar":"",
     8                 "celebrityId":0,
     9                 "celebrityName":"",
    10                 "rank":0,
    11                 "title":""
    12             },
    13             "authInfo":"",
    14             "cityName":"贵阳",
    15             "content":"必须十分,借钱都要看的一部电影。",
    16             "filmView":false,
    17             "id":1045570589,
    18             "isMajor":false,
    19             "juryLevel":0,
    20             "majorType":0,
    21             "movieId":1208282,
    22             "nick":"nick",
    23             "nickName":"nickName",
    24             "oppose":0,
    25             "pro":false,
    26             "reply":0,
    27             "score":5,
    28             "spoiler":0,
    29             "startTime":"2018-11-22 23:52:58",
    30             "supportComment":true,
    31             "supportLike":true,
    32             "sureViewed":1,
    33             "tagList":{
    34                 "fixed":[
    35                     {
    36                         "id":1,
    37                         "name":"好评"
    38                     },
    39                     {
    40                         "id":4,
    41                         "name":"购票"
    42                     }
    43                 ]
    44             },
    45             "time":"2018-11-22 23:52",
    46             "userId":1871534544,
    47             "userLevel":2,
    48             "videoDuration":0,
    49             "vipInfo":"",
    50             "vipType":0
    51         }
    52     ]
    53 }
    54

    如此多的数据,我们感兴趣的只有以下这几个字段:

    nickName, cityName, content, startTimescore

    接下来,进行我们比较重要的数据处理,从拿到的 JSON 数据中解析出需要的字段:

     1 def parseInfo(data): 
     2     data = json.loads(html)['cmts']
     3     for item in data:
     4         yield{
     5             'date':item['startTime'],
     6             'nickname':item['nickName'],
     7             'city':item['cityName'],
     8             'rate':item['score'],
     9             'conment':item['content']
    10         }

    拿到数据后,我们就可以开始数据分析了。但是为了避免频繁地去猫眼请求数据,需要将数据存储起来,在这里,笔者使用的是 SQLite3,放到数据库中,更加方便后续的处理。存储数据的代码如下:

     1 def saveCommentInfo(moveId, nikename, comment, rate, city, start_time)
     2     conn = sqlite3.connect('unknow_name.db')
     3     conn.text_factory=str
     4     cursor = conn.cursor()
     5     ins="insert into comments values (?,?,?,?,?,?)"
     6     v = (moveId, nikename, comment, rate, city, start_time)
     7     cursor.execute(ins,v)
     8     cursor.close()
     9     conn.commit()
    10     conn.close()

    数据处理

    因为前文我们是使用数据库来进行数据存储的,因此可以直接使用 SQL 来查询自己想要的结果,比如评论前五的城市都有哪些:

    SELECT  city, count(*) rate_count  FROM comments GROUP BY city ORDER BY rate_count DESC LIMIT 5

    结果如下:

    在这里插入图片描述

    从上面的数据, 我们可以看出来,来自北京的评论数最多。

    不仅如此,还可以使用更多的 SQL 语句来查询想要的结果。比如每个评分的人数、所占的比例等。如笔者有兴趣,可以尝试着去查询一下数据,就是如此地简单。

    而为了更好地展示数据,我们使用 Pyecharts 这个库来进行数据可视化展示。

    根据从猫眼拿到的数据,按照地理位置,直接使用 Pyecharts 来在中国地图上展示数据:

     1 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
     2 city = data.groupby(['city'])
     3 city_com = city['rate'].agg(['mean','count'])
     4 city_com.reset_index(inplace=True)
     5 data_map = [(city_com['city'][i],city_com['count'][i]) for i in range(0,city_com.shape[0])]
     6 geo = Geo("GEO 地理位置分析",title_pos = "center",width = 1200,height = 800)
     7 while True:
     8     try:
     9         attr,val = geo.cast(data_map)
    10         geo.add("",attr,val,visual_range=[0,300],visual_text_color="#fff",
    11                 symbol_size=10, is_visualmap=True,maptype='china')
    12 13     except ValueError as e:
    14         e = e.message.split("No coordinate is specified for ")[1]
    15         data_map = filter(lambda item: item[0] != e, data_map)
    16     else :
    17         break
    18 geo.render('geo_city_location.html')

    注:使用 Pyecharts 提供的数据地图中,有一些猫眼数据中的城市找不到对应的从标,所以在代码中,GEO 添加出错的城市,我们将其直接删除,过滤掉了不少的数据。

    使用 Python,就是如此简单地生成了如下地图: 在这里插入图片描述

    从可视化数据中可以看出,既看电影又评论的人群主要分布在中国东部,又以北京、上海、成都、深圳最多。虽然能从图上看出来很多数据,但还是不够直观,如果想看到每个省/市的分布情况,我们还需要进一步处理数据。

    而在从猫眼中拿到的数据中,城市包含数据中具备县城的数据,所以需要将拿到的数据做一次转换,将所有的县城转换到对应省市里去,然后再将同一个省市的评论数量相加,得到最后的结果。

     1 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
     2 city = data.groupby(['city'])
     3 city_com = city['rate'].agg(['mean','count'])
     4 city_com.reset_index(inplace=True)
     5 fo = open("citys.json",'r')
     6 citys_info = fo.readlines()
     7 citysJson = json.loads(str(citys_info[0]))
     8 data_map_all = [(getRealName(city_com['city'][i], citysJson),city_com['count'][i]) for i in range(0,city_com.shape[0])]
     9 data_map_list = {}
    10 for item in data_map_all:
    11     if data_map_list.has_key(item[0]):
    12         value = data_map_list[item[0]]
    13         value += item[1]
    14         data_map_list[item[0]] = value
    15     else:
    16         data_map_list[item[0]] = item[1]
    17 data_map = [(realKeys(key), data_map_list[key] ) for key in data_map_list.keys()]
    18 def getRealName(name, jsonObj):    
    19     for item in jsonObj:
    20         if item.startswith(name) :
    21             return jsonObj[item]
    22     return name
    23 def realKeys(name):
    24     return name.replace(u"", "").replace(u"", "")
    25                .replace(u"回族自治区", "").replace(u"维吾尔自治区", "")
    26                .replace(u"壮族自治区", "").replace(u"自治区", "")
    
    

    经过上面的数据处理,使用 Pyecharts 提供的 map 来生成一个按省/市来展示的地图:

     1 def generateMap(data_map):
     2     map = Map("城市评论数", width= 1200, height = 800, title_pos="center")
     3     while True:
     4         try:
     5             attr,val = geo.cast(data_map)
     6             map.add("",attr,val,visual_range=[0,800],
     7                     visual_text_color="#fff",symbol_size=5,
     8                     is_visualmap=True,maptype='china',
     9                     is_map_symbol_show=False,is_label_show=True,is_roam=False, 
    10                     )
    11         except ValueError as e:
    12             e = e.message.split("No coordinate is specified for ")[1]
    13             data_map = filter(lambda item: item[0] != e, data_map)
    14         else :
    15             break
    16     map.render('city_rate_count.html')

    在这里插入图片描述

    当然,我们还可以来可视化一下每一个评分的人数,这个地方采用柱状图来显示:

     1 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
     2 # 按评分分类
     3 rateData = data.groupby(['rate'])
     4 rateDataCount = rateData["date"].agg([ "count"])
     5 rateDataCount.reset_index(inplace=True)
     6 count = rateDataCount.shape[0] - 1
     7 attr = [rateDataCount["rate"][count - i] for i in range(0, rateDataCount.shape[0])]    
     8 v1 = [rateDataCount["count"][count - i] for i in range(0, rateDataCount.shape[0])]
     9 bar = Bar("评分数量")
    10 bar.add("数量",attr,v1,is_stack=True,xaxis_rotate=30,yaxix_min=4.2,
    11         xaxis_interval=0,is_splitline_show=True)
    12 bar.render("html/rate_count.html")

    画出来的图,如下所示,在猫眼的数据中,五星好评的占比超过了 50%,比豆瓣上 34.8% 的五星数据好很多。

    在这里插入图片描述

    从以上观众分布和评分的数据可以看到,这一部剧,观众朋友还是非常地喜欢。前面,从猫眼拿到了观众的评论数据。现在,笔者将通过 jieba 把评论进行分词,然后通过 Wordcloud 制作词云,来看看,观众朋友们对《无名之辈》的整体评价:

     1 data = pd.read_csv(f,sep='{',header=None,encoding='utf-8',names=['date','nickname','city','rate','comment'])
     2 comment = jieba.cut(str(data['comment']),cut_all=False)
     3 wl_space_split = " ".join(comment)
     4 backgroudImage = np.array(Image.open(r"./unknow_3.png"))
     5 stopword = STOPWORDS.copy()
     6 wc = WordCloud(width=1920,height=1080,background_color='white',
     7     mask=backgroudImage,
     8     font_path="./Deng.ttf",
     9     stopwords=stopword,max_font_size=400,
    10     random_state=50)
    11 wc.generate_from_text(wl_space_split)
    12 plt.imshow(wc)
    13 plt.axis("off")
    14 wc.to_file('unknow_word_cloud.png')

    导出:

    在这里插入图片描述 .

  • 相关阅读:
    [国家集训队]墨墨的等式(同余最短路)
    [洛谷P2575]高手过招
    [CSP校内集训]rank
    杀人游戏(tarjan思维好题)
    骑士游戏(spfa好题)
    机房模拟测试4:计数类dp+水题+树上计数
    机房测试模拟2:模拟+数学+数位dp
    机房测试11:最小生成树(最小生成树+二分)
    机房测试模拟1(day2):矩阵+树上贪心+bfs+状压
    机房测试16:字符串专题(AC自动机+dp+kmp)
  • 原文地址:https://www.cnblogs.com/Qqun821460695/p/11953720.html
Copyright © 2011-2022 走看看