用Python調(diào)教微信收壕,實(shí)現(xiàn)自動(dòng)回復(fù) 和 微信好友分布,好友性別圖啼器,好友標(biāo)簽

官方華麗的術(shù)語---略

一個(gè)自動(dòng)回復(fù)機(jī)器人

微信自上線以來,一直沒有自動(dòng)回復(fù)的功能端壳,想必是有他們的理念。但是有些人群损谦,確實(shí)對(duì)此功能有一定需求,我舉兩個(gè)栗子:

不愿時(shí)刻被消息打擾的人
消息需要批量處理的人們(比如微商)

設(shè)計(jì)了幾個(gè)功能:

[x] 收到消息立即自動(dòng)回復(fù)
[x] 收到消息延遲指定時(shí)間回復(fù)
[x] 對(duì)不同好友定制不同的回復(fù)內(nèi)容
[x] 在手機(jī)端隨時(shí)進(jìn)行控制

itchat的原理是通過掃碼進(jìn)行遠(yuǎn)程微信網(wǎng)頁端的登錄照捡,然后通過在移動(dòng)端進(jìn)行操作,網(wǎng)頁端進(jìn)行響應(yīng)栗精,來實(shí)現(xiàn)一些功能,雖然似乎繞了個(gè)彎子,但是在微信的限制下鹿寨,這似乎已經(jīng)是一種最佳的方式了,猶如戴著鐐銬起舞脚草。

我們可以先通過設(shè)定幾個(gè)全局變量來做作為功能的開關(guān)和保存數(shù)據(jù)的容器。

#自動(dòng)回復(fù)開關(guān)
SWITCH_REPLY=True
#延遲回復(fù)開關(guān)
SWITCH_DELAY=False
#延遲時(shí)間
DELAY_TIME=120
#消息前綴開關(guān)
SWITCH_PREFIX=True
#消息前綴內(nèi)容
PREFIX_CONTENT="[自動(dòng)回復(fù)]"
#回復(fù)內(nèi)容字典
REPLY_DICT={}
#延遲回復(fù)字典
DELAY_REPLY_DICT={}

然后通過判斷web端在”文件管理器“中接收到的字符串指令來進(jìn)行不同操作馏慨,這一部分的代碼比較簡單且冗長,這里就不貼出來了写隶,完整源碼地址將會(huì)在文末給出。

假如此時(shí)我們收到了朋友的消息樟澜,需要程序給出自動(dòng)回復(fù)。

#獲取發(fā)送消息的朋友的信息
    target_friend=itchat.search_friends(userName = msg['FromUserName'])
    if target_friend:
        #獲取ta的昵稱
        nickName=target_friend['NickName']
        if not REPLY_DICT.__contains__(nickName):
            #設(shè)置默認(rèn)回復(fù)
            REPLY_DICT[nickName]="抱歉我有事暫未看到消息秩贰,稍后回復(fù),若有急事可以電話聯(lián)系(?ω?`)"
        
        reply_content=REPLY_DICT[nickName]
        #判斷自動(dòng)回復(fù)開關(guān)
        if SWITCH_REPLY:
            #判斷延時(shí)回復(fù)開關(guān)
            if SWITCH_DELAY:
                localtime = time.time()
                DELAY_REPLY_DICT[nickName]=[localtime,msg['FromUserName']]
                print (DELAY_REPLY_DICT)
                
            if not SWITCH_DELAY:
                #判斷消息前綴開關(guān)
                if SWITCH_PREFIX:
                    reply_content = PREFIX_CONTENT + REPLY_DICT[nickName]
                else:
                    reply_content = REPLY_DICT[nickName]
                #發(fā)送消息
                itchat.send(reply_content, toUserName=msg['FromUserName'])

收到朋友消息即時(shí)進(jìn)行自動(dòng)回復(fù)是很簡單的毒费,但是如何去做延時(shí)發(fā)送回復(fù)消息呢愈魏?(至于做這個(gè)功能有沒有必要的問題可以先擱置觅玻,不過我認(rèn)為在很多場(chǎng)景下是需要這個(gè)功能的培漏,大家也可以在評(píng)論區(qū)討論在什么場(chǎng)景下需要延遲自動(dòng)回復(fù))現(xiàn)在就回到技術(shù)的問題,如何實(shí)現(xiàn)可設(shè)置時(shí)間的延時(shí)自動(dòng)回復(fù)牌柄。
我先談一談我的想法,拋磚引玉珊佣。一般發(fā)送消息需要用到隊(duì)列蹋宦,進(jìn)行入隊(duì)和出隊(duì)咒锻,我在這里設(shè)置了一個(gè)字典來保存消息發(fā)送者的數(shù)據(jù)。鍵為消息發(fā)送者的昵稱惑艇,值是一個(gè)長度為2的數(shù)組,分別保存消息發(fā)送者的微信id和接收消息時(shí)的時(shí)間戳。這樣我將每條發(fā)送過來的朋友信息保存在這個(gè)字典中须板,再通過將設(shè)定延遲時(shí)間同消息時(shí)間戳求和與當(dāng)前時(shí)間戳進(jìn)行對(duì)比,若當(dāng)前時(shí)間戳較大习瑰,那么執(zhí)行發(fā)送消息的操作秽荤。
此時(shí)再開啟一個(gè)線程作為定時(shí)任務(wù),定時(shí)去檢測(cè)字典中每條數(shù)據(jù)是否到達(dá)了發(fā)送的臨界要求(當(dāng)前時(shí)間戳>=消息時(shí)間戳+設(shè)定的延遲時(shí)間)Python中有個(gè)專門做定時(shí)任務(wù)的模塊叫sched窃款,但是我嘗試了一下,sched會(huì)阻塞當(dāng)前主線程晨继,也會(huì)阻塞itchat的線程,所以并不合適紊扬。這里我還是采用了threading的Timer來充當(dāng)定時(shí)器,不過要注意使用遞歸餐屎,否則將會(huì)出現(xiàn)運(yùn)行一次就結(jié)束的情況。

#延遲發(fā)送消息的函數(shù)
def delay_reply():
    #print("開始執(zhí)行")
    global DELAY_REPLY_DICT
    if SWITCH_DELAY:
        while len(DELAY_REPLY_DICT)>0:
            localtime = time.time()
            # print (localtime)
            # print (DELAY_REPLY_DICT[item][0])
            # print (int(DELAY_TIME))
            for item in list(DELAY_REPLY_DICT.keys()):
                if SWITCH_REPLY:
                    reply_content = item + "," + str(round(int(DELAY_TIME) / 60, 1)) + "分鐘過去了腹缩," + REPLY_DICT[item]
                    itchat.send(reply_content, toUserName=DELAY_REPLY_DICT[item][1])
                    # print ("發(fā)送消息")
                    del DELAY_REPLY_DICT[item]
            print (DELAY_REPLY_DICT)

    global timer1
    timer1=threading.Timer(DELAY_TIME,delay_reply)
    timer1.start()

到此為止藏鹊,主要的功能已經(jīng)實(shí)現(xiàn)了盘寡,我用一個(gè)測(cè)試賬號(hào)對(duì)我的微信進(jìn)行了各種測(cè)試菇曲,看一下以下截圖:


WechatIMG712.jpeg

WechatIMG710.jpeg

這時(shí)功能基本已經(jīng)完成了萧朝,這就結(jié)束了嗎竖配?別著急,再想想有沒有需要完善一下的地方盯漂?用過微信web端的同學(xué)應(yīng)該知道,當(dāng)web端長期處于未操作的狀態(tài)下會(huì)失去連接羞延。在我們這個(gè)情況下嗤谚,假如你長時(shí)間未收到微信消息,后臺(tái)程序?qū)?huì)與微信失去連接籍胯,再次開啟需要登上服務(wù)器重啟程序,這顯然非常麻煩。有沒有什么簡單的解決辦法呢?我想到一些應(yīng)用的后臺(tái)通常會(huì)做一道心跳檢測(cè)機(jī)制,那我就模仿這個(gè)思路炸裆,定時(shí)給我的”文件管理器“發(fā)一個(gè)字符串,來保持連接烹看。

def keep_alive():
text="保持登錄"
itchat.send(text, toUserName="filehelper")
global timer2
timer2 = threading.Timer(60*60,keep_alive)
timer2.start()

最后,我們需要將這個(gè)程序發(fā)布在服務(wù)器上惯殊,讓它全天候?yàn)槲业奈⑿欧?wù)。
image

這里需要注意土思,如果僅用python xxxx.py來運(yùn)行的話,關(guān)閉shell會(huì)導(dǎo)致進(jìn)程結(jié)束己儒,所以我們需要使用nohup python xxxx.py &來全方位守護(hù)進(jìn)程,這里啰嗦一句闪湾,nohup和&的功能是不一樣的,很多人容易混淆途样,感興趣的話可以去查下資料區(qū)分一下。

到此何暇,微信經(jīng)過了我們的稍稍調(diào)教,已經(jīng)乖了一點(diǎn)赖晶。但是辐烂,這遠(yuǎn)遠(yuǎn)不夠,思路可以繼續(xù)拓展纠修,比如實(shí)現(xiàn)通過手機(jī)微信來控制電腦的開關(guān)機(jī),電腦軟件的啟動(dòng)關(guān)閉扣草,都是可以的,甚至實(shí)現(xiàn)控制家中的空調(diào)颜屠,理論上也未嘗不可,只是比較有難度甫窟。

簡單分析微信好友信息

上文提到,既然我們能通過itchat來獲取好友的信息粗井,name自然會(huì)有很多好玩的信息(這里不做具體解析)。

性別比例
def get_sex():
# 獲取好友數(shù)據(jù)
my_friends = itchat.get_friends(update=True)[0:]
sex = {"male": 0, "female": 0, "other": 0}
for item in my_friends[1:]:
    s = item["Sex"]
    if s == 1:
        sex["male"] += 1
    elif s == 2:
        sex["female"] += 1
    else:
        sex["other"] += 1
total = len(my_friends[1:])

# 開始畫餅圖
attr = list(sex.keys())
v1 = list(sex.values())
pie = Pie("好友性別比例")
pie.add("", attr, v1, v1, is_label_show=True)
pie.render(path="sex_html/sex.html")
性別比例
全國好友省級(jí)分布
def friends_province():
# 獲取好友省份
province= get_data("Province")
# 分類
province_distribution = {}
for item in province:
    #刪除英文省份懒构,因?yàn)橹袊貓D表中沒有
    if bool(re.search('[a-z]',item)):
        continue
    elif not province_distribution.__contains__(item):
        province_distribution[item] = 1
    else:
        province_distribution[item] += 1
#將省份名為空的刪除
province_distribution.pop('')
#提取地圖接口需要的數(shù)據(jù)格式
# print(province_distribution)
province_keys=province_distribution.keys()
province_values=province_distribution.values()

return province_keys,province_values
注意:這里需要自己安裝地圖耘擂,否則會(huì)只顯示南海諸島問題胆剧,http://www.reibang.com/p/20fd061d0b96

解決方案醉冤,手動(dòng)安裝地圖

  1. 全球國家地圖: echarts-countries-pypkg (1.9MB): 世界地圖和 213 個(gè)國家秩霍,包括中國地圖
  2. 中國省級(jí)地圖: echarts-china-provinces-pypkg (730KB):23 個(gè)省冤灾,5 個(gè)自治區(qū)
  3. 中國市級(jí)地圖: echarts-china-cities-pypkg (3.8MB):370 個(gè)中國城市

需要這些地圖的朋友,可以裝 pip 命令行:

pip install echarts-countries-pypkg
pip install echarts-china-provinces-pypkg
pip install echarts-china-cities-pypkg

特別注明韵吨,中國地圖在 echarts-countries-pypkg 里。

全國好友分布
好友標(biāo)簽
def friends_signature():
signature = get_data("Signature")
wash_signature=[]
for item in signature:
    #去除emoji表情等非文字
    if "emoji" in item:
        continue
    rep = re.compile("1f\d+\w*|[<>/=【】『』♂ω]")
    item=rep.sub("", item)
    wash_signature.append(item)

words="".join(wash_signature)

print(wash_signature)

wordlist = jieba.cut(words, cut_all=True)
word_space_split = " ".join(wordlist)

global NickName
global Sex

# print(NickName, Sex)

# 圖片的作用:生成的圖片是這個(gè)圖片的兩倍大小
# 根據(jù)性別選擇對(duì)應(yīng)的性別模板圖
if Sex == 2:
    coloring = np.array(Image.open("standard/girl.jpg"))
elif Sex == 1:
    coloring = np.array(Image.open("standard/boy.jpg"))
else:
    coloring = np.array(Image.open("standard/num.jpg"))


# simkai.ttf 必填項(xiàng) 識(shí)別中文的字體椿疗,例:simkai.ttf,
my_wordcloud = WordCloud(background_color="white", max_words=800,
                         mask=coloring, max_font_size=120, random_state=30, scale=2,font_path="fonts/STKAITI.TTF").generate(word_space_split)

image_colors = ImageColorGenerator(coloring)
plt.imshow(my_wordcloud.recolor(color_func=image_colors))
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()

# 保存圖片
my_wordcloud.to_file('Signature/signature.png')

說明兩點(diǎn):
1届榄、一定要有標(biāo)簽樣版圖,生成對(duì)應(yīng)樣式
2铝条、要添加識(shí)別中文的字體

好友標(biāo)簽

Github:https://github.com/silencesmile/Young_WeChart
如果您喜歡靖苇,希望能給個(gè)小星星

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末班缰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子埠忘,更是在濱河造成了極大的恐慌,老刑警劉巖莹妒,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異旨怠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)鉴腻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拘哨,“玉大人信峻,你說我怎么就攤上這事倦青№镂瑁” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵踢步,是天一觀的道長。 經(jīng)常有香客問我获印,道長,這世上最難降的妖魔是什么兼丰? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮鳍征,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘艳丛。我一直安慰自己匣掸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布霎匈。 她就那樣靜靜地躺著,像睡著了一般砰粹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碱璃,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音嵌器,去河邊找鬼。 笑死爽航,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的讥珍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼衷佃,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了氏义?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤惯悠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后克婶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡情萤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了紫岩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泉蝌,死狀恐怖揩晴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情硫兰,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布劫映,位于F島的核電站,受9級(jí)特大地震影響泳赋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜喇喉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拣技。 院中可真熱鬧,春花似錦膏斤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衔掸。三九已至俺抽,卻和暖如春敞映,著一層夾襖步出監(jiān)牢的瞬間磷斧,已是汗流浹背振愿。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工弛饭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冕末,地道東北人侣颂。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像憔晒,于是被迫代替她去往敵國和親藻肄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1攻询、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_x閱讀 15,968評(píng)論 3 119
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理州弟,服務(wù)發(fā)現(xiàn)钧栖,斷路器婆翔,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • by 憶水寒的清淺拾光 茵茵碧草拯杠,新新楊柳 趕羊兒的鞭子不再有 溪水飛濺浙滤,蝌蚪鞋里游 笑聲停在了那年的山溝溝 黃杏...
    憶水寒的清淺拾光閱讀 631評(píng)論 3 7
  • 講個(gè)故事吧 是武俠。 清明纺腊,不是晴明畔咧。 清明是個(gè)女孩子揖膜,用劍的女孩子誓沸。 但是她的師父韓如雅是用扇子的壹粟。當(dāng)然拜隧,清明的...
    Aardekonijneten閱讀 273評(píng)論 1 1
  • 文/月小兮 那天朋友聚會(huì)趁仙,不知怎么談?wù)摰交橐觥?未婚的小云對(duì)已婚的夢(mèng)凡說:“如果哪個(gè)男人給我二百萬洪添,我就做他情人”...
    月小兮閱讀 410評(píng)論 3 5