├── Signature └── 微信好友标签 ├── sex_html └── 微信好友性别比例 ├── friends_html └── 微信好友全国分布图 ├── QR.png ├── README.md ├── fonts └── simkai.ttf ├── standard ├── boy.jpg ├── girl.png └── num.jpg ├── .idea └── vcs.xml ├── .gitignore ├── wx_friends.py └── wx_reply.py /Signature/微信好友标签: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sex_html/微信好友性别比例: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /friends_html/微信好友全国分布图: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /QR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silencesmile/Young_WeChart/HEAD/QR.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Young_WeChart 2 | 微信的自动回复 和 微信好友分布,好友性别图,关键字标签 3 | 4 | 关键信息慢慢填充 5 | -------------------------------------------------------------------------------- /fonts/simkai.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silencesmile/Young_WeChart/HEAD/fonts/simkai.ttf -------------------------------------------------------------------------------- /standard/boy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silencesmile/Young_WeChart/HEAD/standard/boy.jpg -------------------------------------------------------------------------------- /standard/girl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silencesmile/Young_WeChart/HEAD/standard/girl.png -------------------------------------------------------------------------------- /standard/num.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/silencesmile/Young_WeChart/HEAD/standard/num.jpg -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | .idea 6 | .DS_Store 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | .hypothesis/ 50 | .pytest_cache/ 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | db.sqlite3 60 | 61 | # Flask stuff: 62 | instance/ 63 | .webassets-cache 64 | 65 | # Scrapy stuff: 66 | .scrapy 67 | 68 | # Sphinx documentation 69 | docs/_build/ 70 | 71 | # PyBuilder 72 | target/ 73 | 74 | # Jupyter Notebook 75 | .ipynb_checkpoints 76 | 77 | # pyenv 78 | .python-version 79 | 80 | # celery beat schedule file 81 | celerybeat-schedule 82 | 83 | # SageMath parsed files 84 | *.sage.py 85 | 86 | # Environments 87 | .env 88 | .venv 89 | env/ 90 | venv/ 91 | ENV/ 92 | env.bak/ 93 | venv.bak/ 94 | 95 | # Spyder project settings 96 | .spyderproject 97 | .spyproject 98 | 99 | # Rope project settings 100 | .ropeproject 101 | 102 | # mkdocs documentation 103 | /site 104 | 105 | # mypy 106 | .mypy_cache/ 107 | -------------------------------------------------------------------------------- /wx_friends.py: -------------------------------------------------------------------------------- 1 | import itchat 2 | from pyecharts import Bar,Pie,Geo,Map 3 | import re 4 | import jieba 5 | import matplotlib.pyplot as plt 6 | from wordcloud import WordCloud, ImageColorGenerator 7 | import numpy as np 8 | import PIL.Image as Image 9 | 10 | 11 | # 定义两个全局属性:NickName Sex 12 | NickName = "" 13 | Sex = 0 14 | 15 | 16 | def get_sex(): 17 | # 获取好友数据 18 | my_friends = itchat.get_friends(update=True)[0:] 19 | sex = {"male": 0, "female": 0, "other": 0} 20 | for item in my_friends[1:]: 21 | s = item["Sex"] 22 | if s == 1: 23 | sex["male"] += 1 24 | elif s == 2: 25 | sex["female"] += 1 26 | else: 27 | sex["other"] += 1 28 | total = len(my_friends[1:]) 29 | 30 | # 开始画饼图 31 | attr = list(sex.keys()) 32 | v1 = list(sex.values()) 33 | pie = Pie("好友性别比例") 34 | pie.add("", attr, v1, v1, is_label_show=True) 35 | pie.render(path="sex_html/sex.html") 36 | 37 | def get_data(type): 38 | result=[] 39 | my_friends = itchat.get_friends(update=True)[0:] 40 | 41 | # 获取作者信息 42 | temp = itchat.get_friends(update=True)[0:1] 43 | auth = temp[0] 44 | 45 | # 46 | global NickName 47 | global Sex 48 | NickName = auth.get("NickName") 49 | Sex = auth.get("Sex") 50 | 51 | for item in my_friends: 52 | result.append(item[type]) 53 | 54 | return result 55 | 56 | def friends_province(): 57 | # 获取好友省份 58 | province= get_data("Province") 59 | # 分类 60 | province_distribution = {} 61 | for item in province: 62 | #删除英文省份,因为中国地图表中没有 63 | if bool(re.search('[a-z]',item)): 64 | continue 65 | elif not province_distribution.__contains__(item): 66 | province_distribution[item] = 1 67 | else: 68 | province_distribution[item] += 1 69 | #将省份名为空的删除 70 | province_distribution.pop('') 71 | #提取地图接口需要的数据格式 72 | # print(province_distribution) 73 | province_keys=province_distribution.keys() 74 | province_values=province_distribution.values() 75 | 76 | return province_keys,province_values 77 | 78 | 79 | def friends_signature(): 80 | signature = get_data("Signature") 81 | wash_signature=[] 82 | for item in signature: 83 | #去除emoji表情等非文字 84 | if "emoji" in item: 85 | continue 86 | rep = re.compile("1f\d+\w*|[<>/=【】『』♂ω]") 87 | item=rep.sub("", item) 88 | wash_signature.append(item) 89 | 90 | words="".join(wash_signature) 91 | 92 | wordlist = jieba.cut(words, cut_all=True) 93 | word_space_split = " ".join(wordlist) 94 | 95 | global NickName 96 | global Sex 97 | 98 | 99 | # 图片的作用:生成的图片是这个图片的两倍大小 100 | # 根据性别选择对应的性别模板图 101 | if Sex == 2: 102 | coloring = np.array(Image.open("standard/girl.jpg")) 103 | elif Sex == 1: 104 | coloring = np.array(Image.open("standard/boy.jpg")) 105 | else: 106 | coloring = np.array(Image.open("standard/num.jpg")) 107 | 108 | 109 | # simkai.ttf 必填项 识别中文的字体,例:simkai.ttf, 110 | my_wordcloud = WordCloud(background_color="white", max_words=800, 111 | mask=coloring, max_font_size=120, random_state=30, scale=2,font_path="fonts/simkai.ttf").generate(word_space_split) 112 | 113 | image_colors = ImageColorGenerator(coloring) 114 | plt.imshow(my_wordcloud.recolor(color_func=image_colors)) 115 | plt.imshow(my_wordcloud) 116 | plt.axis("off") 117 | plt.show() 118 | 119 | # 保存图片 120 | my_wordcloud.to_file('Signature/signature.png') 121 | 122 | if __name__ == '__main__': 123 | 124 | # False 每次登陆需要扫码 True可自动登录 125 | itchat.auto_login(False) 126 | 127 | 128 | # 微信好友省份分布 129 | 130 | attr,value=friends_province() 131 | 132 | map = Map("我的微信好友分布", "@" + NickName ,width=1200, height=600) 133 | map.add("", attr, value, maptype='china', is_visualmap=True, 134 | visual_text_color='#000') 135 | map.render(path="friends_html/friends.html") 136 | 137 | 138 | # 词云 139 | friends_signature() 140 | 141 | # 性别图可以使用 142 | get_sex() 143 | -------------------------------------------------------------------------------- /wx_reply.py: -------------------------------------------------------------------------------- 1 | import itchat 2 | from itchat.content import * 3 | import time 4 | import re 5 | import threading 6 | 7 | 8 | #自动回复开关 9 | SWITCH_REPLY=True 10 | #延迟回复开关 11 | SWITCH_DELAY=False 12 | #延迟时间 13 | DELAY_TIME=120 14 | #消息前缀开关 15 | SWITCH_PREFIX=True 16 | #消息前缀内容 17 | PREFIX_CONTENT="[自动回复]" 18 | #回复内容字典 19 | REPLY_DICT={} 20 | #延迟回复字典 21 | DELAY_REPLY_DICT={} 22 | 23 | 24 | 25 | @itchat.msg_register([TEXT,PICTURE,RECORDING],isGroupChat=False) 26 | def auto_reply(msg): 27 | global SWITCH_REPLY 28 | global SWITCH_DELAY 29 | global DELAY_TIME 30 | global SWITCH_PREFIX 31 | global PREFIX_CONTENT 32 | global REPLY_DICT 33 | global DELAY_REPLY_DICT 34 | 35 | if msg['ToUserName']=='filehelper': 36 | args=re.compile(' ').split(msg['Text']) 37 | try: 38 | if args[0]=='/help': 39 | reply_content=''' 40 | 【功能列表】 41 | 1./help 显示功能列表 42 | 2./switch on 打开自动回复 43 | 3./switch off 关闭自动回复 44 | 4./prefix on 打开消息前缀 45 | 5./prefix off 关闭消息前缀 46 | 6./prefix set [T] 设置前缀内容 47 | 7./delay on 打开延迟回复 48 | 8./delay off 关闭延时回复 49 | 9./delay set [T] 设置延迟时间 50 | 10./dict set [F] [T] 定制好友回复 51 | 11./dict show [F] 显示好友回复 52 | ''' 53 | 54 | elif args[0]=='/switch': 55 | if args[1]=='on': 56 | SWITCH_REPLY=True 57 | reply_content="【系统消息】自动回复已开启" 58 | 59 | elif args[1]=='off': 60 | SWITCH_REPLY=False 61 | reply_content="【系统消息】自动回复已关闭" 62 | 63 | else: 64 | reply_content="【系统消息】未知指令" 65 | 66 | elif args[0]=='/prefix': 67 | if args[1]=='on': 68 | SWITCH_PREFIX=True 69 | reply_content = "【系统消息】回复前缀已开启" 70 | 71 | elif args[1]=='off': 72 | SWITCH_PREFIX=False 73 | reply_content="【系统消息】回复前缀已关闭" 74 | 75 | elif args[1]=='set': 76 | PREFIX_CONTENT="["+args[2]+"]" 77 | reply_content = "【系统消息】回复前缀已设置为:"+PREFIX_CONTENT 78 | 79 | else: 80 | reply_content = "【系统消息】未知指令" 81 | 82 | elif args[0]=='/delay': 83 | if args[1]=='on': 84 | SWITCH_DELAY=True 85 | reply_content="【系统消息】延迟回复已开启" 86 | 87 | elif args[1]=='off': 88 | reply_content="【系统消息】延迟回复已关闭" 89 | 90 | elif args[1]=='set': 91 | DELAY_TIME=args[2] 92 | reply_content="【系统消息】延迟时间被设置为:"+DELAY_TIME 93 | 94 | else: 95 | reply_content = "【系统消息】未知指令" 96 | 97 | elif args[0]=='/dict': 98 | if args[1]=='show': 99 | if REPLY_DICT.__contains__(args[2]): 100 | reply_content="【系统消息】好友["+args[2]+"]的自动回复为:"+REPLY_DICT[args[2]] 101 | else: 102 | reply_content="【系统消息】好友["+args[2]+"]的自动回复暂未设置" 103 | 104 | elif args[1]=='set': 105 | REPLY_DICT[args[2]]=args[3] 106 | reply_content="【系统消息】好友["+args[2]+"的自动回复已设置为:"+REPLY_DICT[args[2]] 107 | else: 108 | reply_content = "【系统消息】未知指令" 109 | else: 110 | reply_content = "【系统消息】未知指令" 111 | 112 | 113 | except: 114 | reply_content="【系统消息】系统异常" 115 | itchat.send(reply_content, toUserName='filehelper') 116 | raise 117 | 118 | itchat.send(reply_content, toUserName='filehelper') 119 | 120 | 121 | else: 122 | #获取发送消息的朋友的信息 123 | target_friend=itchat.search_friends(userName = msg['FromUserName']) 124 | if target_friend: 125 | #获取ta的昵称 126 | nickName=target_friend['NickName'] 127 | if not REPLY_DICT.__contains__(nickName): 128 | #设置默认回复 129 | REPLY_DICT[nickName]="抱歉我有事暂未看到消息,稍后回复,若有急事可以电话联系(•ω•`)" 130 | 131 | reply_content=REPLY_DICT[nickName] 132 | #判断自动回复开关 133 | if SWITCH_REPLY: 134 | #判断延时回复开关 135 | if SWITCH_DELAY: 136 | localtime = time.time() 137 | DELAY_REPLY_DICT[nickName]=[localtime,msg['FromUserName']] 138 | print (DELAY_REPLY_DICT) 139 | 140 | if not SWITCH_DELAY: 141 | #判断消息前缀开关 142 | if SWITCH_PREFIX: 143 | reply_content = PREFIX_CONTENT + REPLY_DICT[nickName] 144 | else: 145 | reply_content = REPLY_DICT[nickName] 146 | #发送消息 147 | itchat.send(reply_content, toUserName=msg['FromUserName']) 148 | 149 | 150 | 151 | def delay_reply(): 152 | print("开始执行") 153 | global DELAY_REPLY_DICT 154 | if SWITCH_DELAY: 155 | while len(DELAY_REPLY_DICT)>0: 156 | localtime = time.time() 157 | # print (localtime) 158 | # print (DELAY_REPLY_DICT[item][0]) 159 | # print (int(DELAY_TIME)) 160 | for item in list(DELAY_REPLY_DICT.keys()): 161 | if SWITCH_REPLY: 162 | reply_content = item + "," + str(round(int(DELAY_TIME) / 60, 1)) + "分钟过去了," + REPLY_DICT[item] 163 | itchat.send(reply_content, toUserName=DELAY_REPLY_DICT[item][1]) 164 | # print ("发送消息") 165 | del DELAY_REPLY_DICT[item] 166 | print (DELAY_REPLY_DICT) 167 | 168 | global timer1 169 | timer1=threading.Timer(DELAY_TIME,delay_reply) 170 | timer1.start() 171 | 172 | def keep_alive(): 173 | text="保持登录" 174 | itchat.send(text, toUserName="filehelper") 175 | global timer2 176 | timer2 = threading.Timer(60*60,keep_alive) 177 | timer2.start() 178 | 179 | if __name__ == '__main__': 180 | timer1 = threading.Timer(DELAY_TIME, delay_reply) 181 | timer1.start() 182 | timer2=threading.Timer(60*60,keep_alive) 183 | timer2.start() 184 | itchat.auto_login() 185 | itchat.run() 186 | # schedule=sched.scheduler(time.time,time.sleep) 187 | # schedule.enter(60,0,delay_reply()) 188 | # schedule.run() 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | --------------------------------------------------------------------------------