Python + AI 微信朋友圈的故事

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013985879/article/details/82887578

 本文主要记录用Python3调itchat来爬取好友信息,并且制作好友性别比例图,好友位置分析,好友所在城市TOP20 和好友个性签名词云等。涉及如下模块:

    itchat 一个开源的微信个人号接口,可以实现信息收发、获取好友列表等功能。

    jieba :python中文分词组件,制作词云的时候会用到

    matpolotlib :python的一个用来画图的库

    wordcloud用来制作词云

1.>>pip install itchat

整个过程分为四步:

   1.获取数据

# -*- coding:utf-8 -*-
import itchat
import logging
import json
import ast
from collections import Counter
# Geo地理坐标类图 Bar 饼状图
from pyecharts import Geo,Bar,Pie
# 导入jieba模块,用于中文分词
import jieba
# 导入matplotlib,用于生成2D图形
import matplotlib.pyplot as plt
# 导入wordcount,用于制作词云图
from wordcloud import WordCloud, STOPWORDS

log = logging.getLogger()
#登录,获取好友列表
def get_data():
    itchat.auto_login()

    friends = itchat.get_friends(update=True)
    # rooms = itchat.get_chatrooms()  #微信群
    # mps = itchat.get_mps(update=True)  #公众号
    # log.info(friends)
    return friends

   2.解析数据

#解析数据
def parse_data(data):
    friends = []
    for item in data[1:]:
        friend = {
          'NickName':item['NickName'],#昵称
          'RemarkName': item['RemarkName'],#备注
          'Sex': item['Sex'], #性别
          'Province': item['Province'], #省份
          'City': item['City'], #城市
          'Signature': item['Signature'],
          'StarFriend': item['StarFriend'], #星标好友 0否1是
          'ContactFlag': item['ContactFlag'], #好友类型和权限 1/3好友 65795/98563不让他看+不看他 65539不看他
        }
        friends.append(friend)
    return friends

   3.存储数据

# 存储数据
def save_txt(friends):
    print("-+"*25,friends)
    for item in friends:
        # item = json.dumps(item, ensure_ascii=False)
        item = str(item)+"\n"
        print("*"*20,item)
        with open(r'E:\0802\data\wechat.txt', 'a', encoding='utf-8') as f:
            f.write(item)

   4.数据可视化

4.1好友性别分析

# 展示数据
def echarts_Sex():
    sex = []
    with open(r"E:\0802\data\wechat.txt", "r", encoding='utf-8') as f:
        rows = f.readlines()
        for row in rows:
            # str 转dict
            row = ast.literal_eval(row) #相比较于json.loads 和eval 更安全和没有潜在的问题(json规定:数组或对象之中的字符串必须使用双引号)
            # print(row['Sex'])
            sex.append(row['Sex'])

    print(len(sex)) #142
    #  统计每个性别的数量
    # attr = ["帅哥","美女","未知"]
    # value = [sex.count(1),sex.count(2),sex.count(0)] #count(x) 注意x是str 还是int
    data = Counter(sex).most_common()
    pie = Pie('好友性别比例','好友总人数: {}'.format(len(sex)))
    attr,value = pie.cast(data)
    for v in attr:
        try:
            if v == 0:
                attr[attr.index(0)] = "未知"
            elif v == 1:
                attr[attr.index(1)] = "帅哥"
            elif v == 2:
                attr[attr.index(2)] = "美女"
        except ValueError as e:
            log.error(e.args)
        except:
            raise
    # radius 饼图的半径,数组的第一项是内半径,第二项是外半径,默认为 [0, 75] 默认设置成百分比,相对于容器高宽中较小的一项的一半。
    # rosetype是否展示成南丁格尔图,通过半径区分数据大小,有'radius'和'area'两种模式。
    #        默认为'radius'
    #             radius:扇区圆心角展现数据的百分比,半径展现数据的大小。
    #             area:所有扇区圆心角相同,仅通过半径展现数据大小。
    # legend_top:图例组件离容器上侧的距离,默认为'top',有'top', 'center', 'bottom'可选,
    #           也可以为百分数,如 "%60"
    # is_legend_show:是否显示顶端图例,默认为True
    pie.add(" ",attr,value,
            radius=[30,75],
            rosetype='area',
            is_label_show=True,
            is_legend_show=True,
            legend_top='bottom'
            )
    pie.render("好友性别比例.html")

好友性别比例效果图: 

4.2 好友位置分析

使用pip 命令下载pyecharts

# 安装地图文件包
pip install echarts-china-provinces-pypkg # 中国省、市、县、区地图 
pip install echarts-china-cities-pypkg 
pip install echarts-china-counties-pypkg 
pip install echarts-china-misc-pypkg 
pip install echarts-countries-pypkg # 全球国家地图 
pip install echarts-united-kingdom-pypkg

#好友位置分析
def friend_location_analyze():

    # 所有城市
    cities = []
    with open(r"E:\0802\data\wechat.txt", "r", encoding='utf-8') as f:
        rows = f.readlines()
        for row in rows:
            # str 转dict
            row = ast.literal_eval(row)  # 相比较于json.loads 和eval 更安全和没有潜在的问题(json规定:数组或对象之中的字符串必须使用双引号)
            # print(row['Sex'])
            city = row['City']
            if city !='':
                if city>=u'\u4e00' and city<=u'\u9fa5': #判断city 是不是汉字,英文暂时匹配不到
                    cities.append(city)
                else:
                    continue

    #统计每个城市出现的次数
    data = Counter(cities).most_common()  #转化为元组列表 [('顺义', 16), ('朝阳', 13), ('海淀', 11)]

    #根据城市数据生成地理坐标图
    geo = Geo("好友位置分布"," ",
              title_color='#fff',
              title_pos='center',
              width=1200,height=600,
              background_color='#404a59'
              )

    attr,value = geo.cast(data)
    # symbol_size:标记图形大小
    # visual_range:指定组件的允许的最小值与最大值。默认为 [0, 100]
    #isual_text_color:两端文本颜色。
    # is_piecewise:是否将组件转换为分段型(默认为连续型),默认为 False
    geo.add(' ',attr,value,
            visual_range=[0,500],
            visual_text_color='#fff',
            symbol_size=15,
            is_visualmap=True,
            is_piecewise=True
            )

    geo.render("好友位置分布.html")


    # 根据城市数据生成柱状图
    data_top20 = Counter(cities).most_common(20)
    bar = Bar("好友所在城市TOP20"," ",
              title_pos='center',
              width=1200,height=600,
              background_color='#404a59'
              )
    attr,value =bar.cast(data_top20)
    bar.add("",attr,value,
            is_visualmap=True,
            visual_text_color='#fff',
            is_more_utils=True,
            is_label_show=True
            )

    bar.render("好友所在城市TOP20.html")

在好友位置分析 调用 geo.add()  函数时,因为spider取到的数据和pyecharts 维护的城市基础数据(city_coordinates.json)个别不一致(比如爬取到的是北京的海淀,而pyecharts 维护的是北京的海淀区,这样匹配Key 的时候,匹配不到。 )

通过源码发现,是get_coordinate()方法处理的get(Key) 的逻辑,修改pyecharts模块 coordinates.py源码: 重新匹配key

    def get_coordinate(self, city, region):
        region = self.ensure_two_digit_iso_code(region)
        if region not in self.geo_coordinates:
            self._load_data_into_memory(region)
        coordinates = self.geo_coordinates[region].get(city)
        if coordinates is None:
            city_suffix_list = ['省','县','区','市','地区'] #地区:大兴安岭地区
            for city_suffix in city_suffix_list:
                coordinates = self.geo_coordinates[region].get(city+city_suffix)
                if coordinates is not None:
                    return coordinates
        else:
            return coordinates

(PS:"zishen"小白一枚,可能代码有点low,网上暂时没有找到模糊匹配Key 的方案,或许了解更深入时,在优化这种情况)

好友位置分布效果图:

好友所在城市TOP20效果图:

4.3 个性签名词云图

jieba是一个基于Python的分词库,完美支持中文分词,功能强大  (:亲测,网络不是很稳定,多试几次)

pip install jieba

Matplotlib是一个Python的2D绘图库,能够生成高质量的图形,可以快速生成绘图、直方图、功率谱、柱状图、误差图、散点图等

pip install matplotlib

wordcloud是一个基于Python的词云生成类库,可以生成词云图

pip install wordcloud


def SignatureColudImg():
    #获取所有个性签名
    signatures = []
    p = os.path.curdir
    with open(r"E:\0802\data\wechat.txt","r",encoding="utf-8") as f:
        rows = f.readlines()
        for row in rows:
            # str 转 dict
            row = ast.literal_eval(row)
            signature = row['Signature']
            if signature !='' and signature>=u'\u4e00' and signature<=u'\u9fa5':
                log.info(signature)
                signatures.append(signature)
            else:
                continue

    # 设置分词
    """
    Parameter:
    - sentence: The str(unicode) to be segmented.
    - cut_all: Model type. True for full pattern, False for accurate pattern.
    """
    split = jieba.cut(str(signatures),cut_all=False)
    words = " ".join(split) #空格拼接
    print(words)
    #设置屏蔽词,去除个性签名中的表情,特殊符号等
    stopwords = STOPWORDS.copy()
    stopwords.add('span')
    stopwords.add('class')
    stopwords.add('emoji')
    stopwords.add('emoji1f334')
    stopwords.add('emoji1f388')
    stopwords.add('emoji1f33a')
    stopwords.add('emoji1f33c')
    stopwords.add('emoji1f633')

    #导入背景图
    bg_image = plt.imread(r"F:\weChat_project\com\spider\wechat\xinxing.jpg")
    # 设置词云参数,参数分别表示:画布宽高,背景颜色,背景图形状,字体,屏蔽词,最大词的字体大小
    wc = WordCloud(width=1024,height=768,
              background_color='white',
              mask=bg_image,
              font_path='STKAITI.TTF',
              stopwords=stopwords,
              max_font_size=400,
              random_state=50
              )
    #分词数据传入云图
    wc.generate_from_text(words)
    plt.imshow(wc) #绘制云图
    plt.axis('off') #不显示坐标轴

    #保存到本地
    wc.to_file("个性签名词云图.jpg")
    print("success=====")

个性签名词云效果图: (请提前备好 心型图 -百度哟)

参考:CSDN课程

      微信好友大揭秘,使用Python抓取朋友圈数据,通过人脸识别全面分析好友,一起看透你的“朋友圈”

猜你喜欢

转载自blog.csdn.net/u013985879/article/details/82887578