专栏名称: 狗厂
51好读  ›  专栏  ›  狗厂

爬了菊姐2W条微博评论,竟发现“菊粉”都是这样的人!(附带吗)

狗厂  · 掘金  ·  · 2018-06-12 06:16

正文

来自:51CTO技术栈(微信号:blog51cto)

最近一段时间,《创造101》很火,这个火是可以理解的,毕竟这是中国首部女团节目。但是还有一个人不知道为啥突然也火了,那就是我们的菊姐。

关于菊姐为什么会火,网上有很多文章,我就不再赘述了。今天我们就来做一份菊粉陶渊明的用户画像,看看那些 Pick 菊姐的人都有什么特质?

先来看看百度指数,通过百度指数我们看出,菊姐的搜索热度在 5 月 30 开始出现顶峰,5 月 31 开始回落。

王菊百度指数

再来看看微信指数,与百度指数趋势基本一致,但起伏感要稍强于百度指数。

王菊微信指数

我们再来看看菊姐的需求图谱,即与菊姐相关的话题都有哪些。

王菊需求图谱

相关词主要有:创造101,王菊,王菊旧照,王菊年龄,看来大家很关心菊姐的个人信息哈,尤其是旧照。

王菊新旧照

看看菊姐以前的照片,再看看现在的,我只想问一句,菊姐这些年都经历了什么?

了解了这些以后,我们切换到今天的主题,菊粉到底都是哪些人?于是我用 Python 爬了菊姐的两万条微博评论,并做了分析!

数据抓取

爬取数据来源于王菊最新微博评论数据,本次数据采集的思路主要是:

  • 先获取王菊最新几条(关于创造101话题)的微博评论 url

  • 然后依次去遍历每条 url 下面的留言以及 user_id

  • 在拿到 user_id 以后再去依次遍历每个用户的基本信息

具体实现代码如下:

#导入所需库import jsonimport timeimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport matplotlibimport squarifyfrom matplotlib.patches import Polygonfrom mpl_toolkits.basemap import Basemapfrom matplotlib.collections import PatchCollection#获取每条微博评论的url参数def get_comment_parameter():    url = 'https://m.weibo.cn/api/container/getIndex?uid=1773294041&luicode=10000011&lfid=100103type%3D1%26q%3D%E7%8E%8B%E8%8F%8A&           featurecode=20000320&type=uid&value=1773294041&containerid=1076031773294041'    c_r = requests.get(url)    for i in range(2,11):        c_parameter = (json.loads(c_r.text)["data"]["cards"][i]["mblog"]["id"])        comment_parameter.append(c_parameter)    return comment_parameterif __name__ == "__main__":    comment_parameter = []#用来存放微博url参数    comment_url = []#用来存放微博url    user_id = []#用来存放user_id    comment = []#用来存放评论    containerid = []#用来存放containerid    feature = []#用来存放用户信息    id_lose = []#用来存放访问不成功的user_id    get_comment_parameter()    #获取每条微博评论url    c_url_base = 'https://m.weibo.cn/api/comments/show?id='    for parameter in comment_parameter:        for page in range(1,101):#提前知道每条微博只可抓取前100页评论            c_url = c_url_base + str(parameter) + "&page=" + str(page)            comment_url.append(c_url)    #获取每个url下的user_id以及评论    for url in comment_url:        u_c_r = requests.get(url)        try:            for m in range(0,9):#提前知道每个url会包含9条用户信息                one_id = json.loads(u_c_r.text)["data"]["data"][m]["user"]["id"]                user_id.append(one_id)                one_comment = json.loads(u_c_r.text)["data"]["data"][m]["text"]                comment.append(one_comment)        except:            pass    #获取每个user对应的containerid    user_base_url = "https://m.weibo.cn/api/container/getIndex?type=uid&value="    for id in set(user_id):#需要对user_id去重        containerid_url = user_base_url + str(id)        try:            con_r = requests.get(containerid_url)            one_containerid = json.loads(con_r.text)["data"]['tabsInfo']['tabs'][0]["containerid"]            containerid.append(one_containerid)        except:            containerid.append(0)    #获取每个user_id对应的基本信息    #这里需要设置cookie和headers模拟请求    user_agent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"    headers = {"User-Agent":user_agent}    m = 1    for num in zip(user_id,containerid):        url = "https://m.weibo.cn/api/container/getIndex?uid="+str(num[0])+"&luicode=10000011&lfid=100103type%3D1%26q%3D&featurecode=20000320&type=uid&value="+str(num[0])+"&containerid="+str(num[1])        try:            r = requests.get(url,headers = headers,cookies = cookie)            feature.append(json.loads(r.text)["data"]["cards"][1]["card_group"][1]["item_content"].split("  "))            print("成功第{}条".format(m))            m = m + 1            time.sleep(1)        except:            id_lose.append(num[0])    #将featrue建立成DataFrame结构便于后续分析    user_info = pd.DataFrame(feature,columns = ["性别","年龄","星座","国家城市"])

数据预处理

根据用户基本信息的显示顺序,性别、年龄、星座、国家城市,主要用了以下几方面的数据处理逻辑:

  • 对于国家列为空,星座列不空且不包含座字,则认为是国家城市名,则把星座列赋值给国家城市列。

  • 对于国家列为空,星座列也为空,年龄列不为空且不包含岁或座字,则把年龄列赋值给国家城市列。

  • 对于星座列为空,但是年龄列包含座字,则把年龄列赋值给星座列。

  • 对于星座列不包含座的,全部赋值为“未知”。

  • 对于年龄列不包含岁的,全部赋值为“999岁”(为便于后续好筛选)。

  • 对于国家列为空的,全部赋值为“其他”。

具体处理代码如下:

#数据清洗user_info1 = user_info[(user_info["性别"] == "男") | (user_info["性别"] == "女")]#去除掉性别不为男女的部分user_info1 = user_info1.reindex(range(0,5212))#重置索引user_index1 = user_info1[(user_info1["国家城市"].isnull() == True)&(user_info1["星座"].isnull() == False)                         &(user_info1["星座"].map(lambda s:str(s).find("座")) == -1)].indexfor index in user_index1:    user_info1.iloc[index,3] = user_info1.iloc[index,2]user_index2 = user_info1[((user_info1["国家城市"].isnull() == True)&(user_info1["星座"].isnull() == True)                          &(user_info1["年龄"].isnull() == False)&(user_info1["年龄"].map(lambda s:str(s).find("岁")) == -1))].indexfor index in user_index2:    user_info1.iloc[index,3] = user_info1.iloc[index,1]user_index3 = user_info1[((user_info1["星座"].map(lambda s:str(s).find("座")) == -1)&                          (user_info1["年龄"].map(lambda s:str(s).find("座")) != -1))].indexfor index in user_index3:    user_info1.iloc[index,2] = user_info1.iloc[index,1]user_index4 = user_info1[(user_info1["星座"].map(lambda s:str(s).find("座")) == -1)].indexfor index in user_index4:    user_info1.iloc[index,2] = "未知"user_index5 = user_info1[(user_info1["年龄"].map(lambda s:str(s).find("岁")) == -1)].indexfor index in user_index5:    user_info1.iloc[index,1] = "999岁"user_index6 = user_info1[(user_info1["国家城市"].isnull() == True)].indexfor index in user_index6:    user_info1.iloc[index,3] = "其他"

评论多为褒义词

我们抓取了菊姐的最新微博评论,将评论分词以后制作成如下词云图,代码如下:

import foolfrom collections import Counterfrom PIL import Image,ImageSequence  from wordcloud import WordCloud,ImageColorGenerator#因留言结构比较乱,所以先保存到本地做进一步处理pd.DataFrame(comment).to_csv(r"C:UserszhangjunhongDesktopcomment.csv")#处理完以后再次载入进来comment_data = pd.read_excel(r"C:UserszhangjunhongDesktopcomment.xlsx")#将数据转换成字符串text = (",").join(comment_data[0])#进行分词cut_text = ' '.join(fool.cut(text))#将分词结果进行计数c = Counter(cut_text)c.most_common(500)#挑选出词频最高的500词#将结果导出到本地进行再一次清洗,删除一些符号词pd.DataFrame(c.most_common(500)).to_excel(r"C:UserszhangjunhongDesktopenci.xlsx")image = Image.open('C:/Users/zhangjunhong/Desktop/图片1.png')#作为背景形状的图  graph = np.array(image)  #参数分别是指定字体、背景颜色、最大的词的大小、使用给定图作为背景形状  wc = WordCloud(font_path = "C:\Windows\Fonts\simkai.ttf", background_color = 'White', max_words = 150, mask = graph)  fp = pd.read_csv(r"C:UserszhangjunhongDesktopda200.csv",encoding = "gbk")#读取词频文件  name = list(fp.name)#词  value = fp.time#词的频率   dic = dict(zip(name, value))#词频以字典形式存储  wc.generate_from_frequencies(dic)#根据给定词频生成词云 image_color = ImageColorGenerator(graph)  plt.imshow(wc)  plt.axis("off")#不显示坐标轴  plt.show() wc.to_file('C:/Users/zhangjunhong/Desktop/wordcloud.jpg')

分词没有用 jieba 分词,而是用了 fool,据称是最准确的中文分词包。

GitHub 地址:https://github.com/rockyzhengwu/FoolNLTK

排名前三的热词分别是:“加油”、“哈哈”、“菊姐”,可以看出大家对菊姐的态度大多还是支持的态度。

男女比例 1:2

绘制男女比例的饼图ax = user_info1["性别"].value_counts(normalize = True).plot.pie(title = "菊粉男女分布",autopct='%.2f')







请到「今天看啥」查看全文