查看原文
其他

滚!滚?

Peter 尤而小屋 2022-05-28

公众号:尤而小屋
作者:Peter
编辑:Peter

大家好,我是Peter~

微博吃瓜🍉

前段时间微博上吴某和都某的时间闹得沸沸扬扬,着实让大家吃了不少瓜。

Peter从网上获取到了一些用户的评论数据作为数据分析,看看微博用户都是怎么看待这件事情的。

至于事情后面怎么发展,等待法律的公平公正与公正,本文仅作为数据呈现和分析使用

网页规律

本文中的数据是如何获取到的?

微博评论的数据ajax动态加载的,也就是在地址栏中的URL不变的情况返回不同的数据,但是实际发送请求的URL地址肯定是变化的,在谷歌浏览器中加载了4次,生成了不同的URL地址:

main_url = "https://weibo.com/ajax/statuses/buildComments?is_reload=1&id=4660583661568436&is_show_bulletin=2&is_mix=0&count=20&uid=3591355593"

url2 = "https://weibo.com/ajax/statuses/buildComments?is_reload=1&id=4660583661568436&is_show_bulletin=2&is_mix=0&max_id=27722026381139524&count=20&uid=3591355593"

url3 = "https://weibo.com/ajax/statuses/buildComments?is_reload=1&id=4660583661568436&is_show_bulletin=2&is_mix=0&max_id=11156509319242784&count=20&uid=3591355593"

url4 = "https://weibo.com/ajax/statuses/buildComments?is_reload=1&id=4660583661568436&is_show_bulletin=2&is_mix=0&max_id=5162109363544403&count=20&uid=3591355593"

main_url是主评论的url地址,其他的URL地址是明显不同的;url2、url3、url4的差别仅在于max_id的不同。几经周折,终于找到了关键:原来main_url地址下返回的数据中有下页(第二页)max_id的信息:

同样的操作,第二页返回的max_id也是对应到第三页的URL地址中max_id的值。

⚠️总结:通过前一页返回的数据中max_id的值作为下页url地址中max_id的值

爬取字段

1.用户id
2.评论时间comment_time
3.注册微博时间register_time
4.用户城市city
5.用户性别gender
6.评论内容comment
7.评论点赞数comment_like
8.评论回复数comment_reply

给主页main_url发送请求获取到数据,找到我们需要爬取的字段信息(返回数据转成json文件的样子):

再看看一个用户的数据信息:

本文中爬取的字段数据:

1、用户id

2、用户评论时间:comment_time

3、用户微博注册时间:register_time

4、评论内容:comment

5、评论点赞数:comment_like

6、评论回复人数:comment_reply

7、用户性别:gender

8、用户城市:city


前期工作

导入相关库

import pandas as pd
import numpy as np
from snownlp import SnowNLP
import time
import datetime as dt


# 绘图相关
import jieba
import matplotlib.pyplot as plt
from pyecharts.globals import CurrentConfig, OnlineHostType
from pyecharts import options as opts  # 配置项
from pyecharts.charts import Bar, Pie, Line, HeatMap, Funnel, WordCloud, Grid, Page  # 各个图形的类
from pyecharts.commons.utils import JsCode
from pyecharts.globals import ThemeType,SymbolType

import plotly.express as px
import plotly.graph_objects as go

数据导入

通过pandas库将数据读取进来,我们查看前5条数据:

image-20210728004848814

数据探索

数据探索部分包含:

  • 数据大小
  • 数据是否缺失
  • 数据的字段类型,比如两个时间的字段是字符型,这是后续我们要处理的点

数据预处理

对爬取到的数据进行预处理:

  • 评论时间comment_time和注册时间register_time我们改成熟悉的形式
  • 评论comment中有表情符号[],比如[doge]等,我们取出表情符前面的部分
  • 性别从f、m转成女、男

时间预处理

对时间的处理,使用的是datetime库,开头已经导入了并缩写成dt。爬取到的数据使用的是格林威治标准时间,做如下转化:

  • Mon Jul 19 08:06:52 +0800 2021
  • Thu Nov 30 07:47:02 +0800 2017
transfer_std = "%a %b %d %H:%M:%S %z %Y"

df["comment_time"] = df["comment_time"].apply(lambda x: dt.datetime.strptime(x, transfer_std))
df.head()

评论处理

主要是将表情符处理掉:

性别处理

将数据中的f变成女,m变成男,更加直观容易理解

用户画像

用户画像主要从不同的维度来分析用户在评论中的情况,包含:性别、城市、微博年龄、评论点赞数和回复数等

性别

根据性格对用户进行分组统计:

虽然主评论只有1000+,但是从结果中可以看到:吴某某的粉丝还是以女性为主,远高于男性

城市

主要是想知道哪些城市对吴某某的关注度较高。为了方便,我们统一取用户的省份信息:

fig = px.bar(city[::-1],
             x="userid",
             y="city",
             text="userid",
             color="userid",
             orientation="h"
            )

fig.update_traces(textposition="outside")
fig.update_layout(height=800,width=1000)
fig.show()

从条形图中可以看到:

  1. 很多用户没有个人的省份(城市)信息
  2. 从填写的用户中观察到:江苏、浙江、北京、广东等发达省份对吴某某的关注度更高
  3. 海外也有不少的用户在关注

用户微博年龄

表示的是从用户注册到评论该条微博的时间间隔

  • 生成评论时间和注册时间的时间间隔
  • 将时间间隔取出天数days
  • 将days转成年,不足一年则省去
px.scatter(df,x="comment_time",y="days",color="year",size="days")

用户年龄小结:

  1. 吴某某的微博是7.19发的,我们发现19号当天的评论的用户还是占多数
  2. 用户的微博年龄最多高达11年!!!也有不足一年,也就是今年新注册的用户

点赞数

主要是想查看哪些微博评论的点赞数靠前

fig = px.bar(dianzan[::-1],
             x="comment_like",
             y="comment",
             text="comment_like",
             orientation="h"
            )

fig.show()

Peter当时爬取的数据是这条评论点赞数最多:滚!!!

多么的简单粗暴!

回复数

从结果中我们看到,还是这条评论:滚!

点赞数和回复数分布

px.scatter(df,
           x="comment_like",
           y="comment_reply",
           size="days",
           facet_col="year",
           facet_col_wrap=3# 每行最多3个图形
           color="year")

从不同年龄用户的点赞数和回复数中观察到:

  • 用户的年龄在5-10年居多;新用户评论比较少
  • 用户的年龄在5年或者6年的评论点赞数或者回复数集中度较高,用户倾向较一致;其他年龄段的用户相对分散

评论词云图

使用jieba分词来绘制用户评论的词云图:

df1 = df[df["comment"] != ""]  # 筛选出存在评论的数据
comment_list = df["comment"].tolist()

# 分词过程
comment_jieba_list = []
for i in range(len(comment_list)):
   # jieba分词
    seg_list = jieba.cut(str(comment_list[i]).strip(), cut_all=False)
    for each in list(seg_list):
        comment_jieba_list.append(each)
        
# 创建停用词list
def StopWords(filepath):
    stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
    return stopwords

# 传入停用词表的路径
stopwords = StopWords("/Users/peter/Desktop/WeChat/文章/spider/nlp_stopwords.txt")
# 词频统计
comment_result = pd.value_counts(stopword_list).reset_index().rename(columns={"index":"word",0:"number"})
comment_result

绘制全部评论词云图:

rec_words = [tuple(z) for z in zip(comment_result["word"].tolist(), comment_result["number"].tolist())]


# 5、WordCloud模块绘图
c = (
    WordCloud()
    .add("", rec_words, word_size_range=[20100], shape=SymbolType.DIAMOND)
    .set_global_opts(title_opts=opts.TitleOpts(title="微博评论词云图"))
)

c.render_notebook()

我们截图前50个高频词云进行绘图

rec_words = [tuple(z) for z in zip(comment_result["word"].tolist(), comment_result["number"].tolist())]


# 5、WordCloud模块绘图
c = (
    WordCloud()
    .add("", rec_words[:50], word_size_range=[20100], shape=SymbolType.DIAMOND)
    .set_global_opts(title_opts=opts.TitleOpts(title="微博评论词云图"))
)

c.render_notebook()

从全部词云和Top50词云图中观察到:

  1. 滚:还是那么的引人注目😭
  2. 很多的用户在评论中使用了吴某某的名字,或者昵称:凡凡、凡哥,甚至是哥哥
  3. 也有很多用户在给吴某某加油打气:加油、支持、喜欢等
  4. 很多法律相关的词语:法律、监狱、坐牢、违法、司法公正、真相等,说明很多粉丝还是比较理智的看待这件事情

再次郑重声明:本文仅做数据学习和分析展示,事情的后续结果如何,我们相信法律会有一个公平公正公开的结论🍉


推荐阅读


挑战SQL:图解Pandas的数据合并merge

可视化神器Plotly玩转子图

数据分析师=7大主题,24份资料

生日快乐:尤而小屋两周岁啦

55个案例:吃透Python字符串格式化

尤而小屋,一个温馨的小屋。小屋主人,一手代码谋求生存,一手掌勺享受生活,欢迎你的光临


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存