本文主要记录用Python3调itchat来爬取好友信息,并且制作好友性别比例图,好友位置分析,好友所在城市TOP20 和好友个性签名词云等。涉及如下模块:
itchat :一个开源的微信个人号接口,可以实现信息收发、获取好友列表等功能。
jieba :python中文分词组件,制作词云的时候会用到
matpolotlib :python的一个用来画图的库
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课程