想查看微信好友撤回的消息?Python幫你搞定


 

前言
本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。
作者:~wangweijun

Python微信防撤回小程序,

當你用微信和對方聊天時,對方突然撤回了幾條消息,你會好奇嗎?你會很想知道對方撤回了什么嗎? Python實現的微信防撤回小程序,讓你輕松獲取對方撤回的消息內容

 

要說微信最讓人惡心的發明,消息撤回絕對能上榜。

比如你現在正和女朋友用微信聊着天,或者跟自己喜歡的女孩子聊着天,一個不留神,你沒注意到對方發的消息就被她及時撤回了,這時你很好奇,好奇她到底發了什么?於是你打算問問她發了什么,結果她回一句"沒什么"。這一回復,讓你的好奇心更加強烈了,頓時就感覺消息撤回這一功能就是用來折磨人的。

那么有沒有什么辦法能夠知道你心愛的她(他)到底撤回了什么呢?不要着急,Python幫你搞定。如果你還不會寫python小程序,建議你去小編的Python交流.裙 :一久武其而而流一思(數字的諧音)轉換下可以找到了,里面有最新Python教程項目,多跟他們交流,你會進步很快!

模塊介紹

本篇文章將用Python實現微信的防撤回功能,針對微信操作,Python有一個十分強大的庫:itchat。相信沒有使用過也有所耳聞吧。官方是這樣描述它的:

Project description
itchat is a open souce wechat api project for personal account. It enables you to access your personal wechat account through command line.

翻譯過來就是:itchat是一個針對個人帳戶的開放式微信api項目,它使您可以通過命令行訪問您的個人微信帳戶。

既然是針對微信的開發,我們就離不開這個模塊的協助,所以,首先下載該模塊:

pip install itchat

也可以在開發工具Pycharm中直接導入該模塊,Pycharm會提示你下載。

模塊初體驗

考慮到應該有些人從來沒有使用過該模塊,這里對該模塊進行一個簡單的入門。

1、如何登陸微信

既然要操作微信,那么擺在我們面前的問題就是如何登錄微信,登錄微信非常簡單,直接看代碼:

import itchat itchat.login()

沒錯,一句代碼即可完成登錄,運行之后就會彈出一個二維碼,掃描之后在手機上授權登錄,控制台就會提示是否登錄成功。

Login successfully as Y

這樣就說明登錄成功了。

這里需要注意一個問題,就是你會發現每次運行程序都要掃描二維碼登錄,這樣未免太麻煩,有沒有辦法只掃描一次,以后就自動登錄了呢?這當然是可以的。

import itchat itchat.auto_login(hotReload=True)

通過函數名也能知道該方法可以實現自動登錄,運行程序,掃碼登錄之后會在項目路徑下創建一個itchat.pkl文件,該文件用於存儲登錄的狀態,所以千萬不要動它,如果你想換一個微信賬號登錄,就要先把這個文件刪除,因為該文件記錄的是上一個微信的狀態,刪除之后即可登錄。

需要注意:這種方式只能保證你在短時間內無需重復登錄,時間長了,還是需要重新掃碼登錄的。

進行到這里,有些人可能會發現自己的微信登錄不上的情況,據我所知,有些新注冊的微信和長期不使用的微信是無法登錄網頁版微信的,所以這里也會導致登錄不上。如果登錄不上,那也是沒有辦法的,下面的內容也就沒有意義了。

2、獲取好友列表

登錄上微信之后,我們來用一用itchat模塊提供的一些api,比如獲取好友列表。

import itchat itchat.auto_login(hotReload=True) friends = itchat.get_friends() # 好友列表 print(friends)

使用get_friends()函數即可獲取到好友列表的所有好友信息,包括昵稱、備注名、地址、個性簽名、性別等等。

這里我隨意地復制了一個好友的個人信息,當然由於隱私問題,這里的部分信息我用"*"號代替了,我們重點是分析一下這些信息的內容。比如最開始的UserName,這是用戶的唯一標識,相當於身份證號碼,你的每個好友都會有這樣一個標識,每個好友之間肯定都是不一樣的;然后是NickName,這是好友的昵稱;HeadImgUrl是好友的頭像地址;RemarkName是你對好友的備注名;Province是省份等等,這里就不一一介紹了,感興趣的話可以自己去了解一下。

3、如何發送消息給好友

如何發送一條消息給指定的好友呢?也非常簡單:

import itchat itchat.auto_login(hotReload=True) itchat.send('Hello World', toUserName='@f9e42aafa1175b38b60a0be4d651a34c77f2528d9b7784e7aaf415090eca8fa6') 

 

此時的UseName就派上用場了,也就是好友的唯一標識,這樣,我們就給該標識對應的好友發送了一條消息,所以,我們可以這樣改進程序:

import itchat itchat.auto_login(hotReload=True) friends = itchat.get_friends() nickName = '誠信通授權渠道商-老曾' for i in friends: if '誠信通授權渠道商-老曾' == i['NickName']: itchat.send('Hello World', toUserName=i['UserName']) break 

這樣,就可以指定發送給任意好友,通過好友的昵稱在好友列表中進行檢索,找到的話,就獲取該好友的UserName,然后發送消息,也可以通過對好友的備注名(RemarkName)查找,大家可以自己嘗試。

4、裝飾器

關於itchat模塊還有很多功能,這里就不作過多講解了,我們只講關於這次程序的知識點,這里是最后一個內容,裝飾器。

關於裝飾器,一時半會還講不清楚,這里只是簡單介紹一下,裝飾器的作用就是用於拓展原來函數功能的一種函數,目的是在不改變原函數名(或類名)的情況下,給函數增加新的功能。

例如現在有一個函數fun(),你並不知曉函數的實現原理,你肯定也不能去修改這個函數的代碼,而你需要給該函數添加一個輸出開始運行時間和結束運行時間的功能,該如何實現呢?這個時候就可以使用裝飾器。

import time def show_time(fun): def inner(): print(time.time()) fun() print(time.time()) return inner @show_time def fun(): pass fun() 

該如何理解這段程序呢?首先@show_time即是使用一個裝飾器show_time,此時會將裝飾的函數,也就是fun()作為參數傳遞給裝飾器show_time(),我們知道函數作為返回值的話,執行的其實是該函數,所以程序會執行內部函數inner(),此時輸出開始運行時間,然后調用fun()函數(原有的功能不能丟),最后輸出結束運行時間。這樣就通過裝飾器實現了一個函數的功能擴展,這也是典型的面向切面編程思想。

如何獲取好友發送的消息

准備工作做完了,接下來就進入正題了,對於上面的知識點,大家一定要掌握,如果不懂的話,接下來的代碼你可能會很懵。

首先,我們看看該如何獲取到好友發送的消息。

import itchat itchat.auto_login(hotReload=True) @itchat.msg_register(itchat.content.TEXT) def resever_info(msg): print(msg) itchat.run() #保持 

itchat模塊提供了@itchat.msg_register裝飾器來監聽消息,比如這里我們自定義了一個resever_info()函數,並用裝飾器對消息進行監聽,裝飾器中傳入了itchat.content.TEXT類型,這樣監聽的就是文本消息,監聽到輸入之后,裝飾器就會將文本消息傳入resever_info()的參數中。所以,msg就是監聽到的消息內容。

對於@itchat.msg_register裝飾器,它不僅可以監聽文本,還可以監聽語音、圖片、地圖、名片、視頻等等,為了方便,這里我們導入itchat模塊下的content模塊中的全部內容,因為這些消息類型都是在該模塊下聲明的。

TEXT       = 'Text' MAP = 'Map' CARD = 'Card' NOTE = 'Note' SHARING = 'Sharing' PICTURE = 'Picture' RECORDING = VOICE = 'Recording' ATTACHMENT = 'Attachment' VIDEO = 'Video' FRIENDS = 'Friends' SYSTEM = 'System' INCOME_MSG = [TEXT, MAP, CARD, NOTE, SHARING, PICTURE, RECORDING, VOICE, ATTACHMENT, VIDEO, FRIENDS, SYSTEM] 

還有要注意的地方,最后記得調用itchat的run()函數,保持程序運行,否則程序就直接結束了。

接下來我們就可以測試一下了,我讓我的好友發了一條消息給我,控制台就輸出了如下內容:
在這里插入圖片描述

內容很多,我們只挑重要的看。例如FromUserName,這是發送者的標識;ToUserName,這是接收者的標識;Content,這當然就是文本內容了;CreateTime,這是發送時間;注意最后的兩個值:Type,這是消息類型,這里是文本類型Text,然后Text也是文本內容,所以如果想取出好友發送的消息內容的話,用Content和Text都可以。分析過后,取出內容就很簡單了:

import itchat import time from itchat.content import * # 導入itchat下的content模塊 itchat.auto_login(hotReload=True) @itchat.msg_register(TEXT) def resever_info(msg): info = msg['Text'] # 取出文本消息 info_type = msg['Type'] # 取出消息類型 fromUser = itchat.search_friends(userName=msg['FromUserName'])['NickName'] ticks = msg['CreateTime'] # 獲取信息發送的時間 time_local = time.localtime(ticks) dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local) # 格式化日期 print("發送人:" + fromUser + '\n消息類型:' + info_type + '\n發送時間:' + dt + '\n消息內容:' + info) itchat.run(

這里用到了time模塊,用於格式化日期。

為了測試方便,我就自己發了一條消息給別人,自己發的消息也是會被監聽的,看運行結果:

發送人:Y 消息類型:Text 發送時間:2019-11-28 16:19:13 消息內容:土鱉 

再來試試語音和圖片能獲取到嗎?我們回到剛才的代碼:

import itchat from itchat.content import * # 導入itchat下的content模塊 itchat.auto_login(hotReload=True) @itchat.msg_register(TEXT) def resever_info(msg): print(msg) itchat.run() 

運行之后,發送語音和圖片試試,不管怎么發,控制台就是沒反應,這是當然的了,我們還沒對語音和圖片進行監聽呢,修改代碼:

import itchat from itchat.content import * # 導入itchat下的content模塊 itchat.auto_login(hotReload=True) @itchat.msg_register([TEXT, PICTURE, RECORDING]) #添加了對圖片和語音的監聽 def resever_info(msg): print(msg) itchat.run() 

再運行試試,先發送一張圖片,再發送一段語音,控制台輸出了兩段內容,由於篇幅過長,就不貼出來了,無非還是那些信息,發送者,接收者,日期,消息內容等等,這里只需注意圖片和語音的內容:

'Type': 'Picture', 'Text': <function get_download_fn.<locals>.download_fn at 0x0000000003574158> 'Type': 'Recording', 'Text': <function get_download_fn.<locals>.download_fn at 0x0000000002CFED08> 

這是一段地址,通過它我們就能夠將圖片和語音保存起來。

如何保存好友發送的圖片和語音

下面我們對好友發送的圖片和語音進行保存。

import itchat import os from itchat.content import * # 導入itchat下的content模塊 itchat.auto_login(hotReload=True) temp = 'C:/Users/Administrator/Desktop/CrawlerDemo' + '/' + '撤回的消息' # 如果不存在該文件夾,就創建 if not os.path.exists(temp): os.mkdir(temp) @itchat.msg_register([TEXT, PICTURE, RECORDING]) def resever_info(msg): info = msg['Text'] # 取出文本消息 info_type = msg['Type'] # 取出消息類型 name = msg['FileName'] # 取出語音(圖片)文件名 if info_type == 'Recording': # 保存語音 info(temp + '/' + name) elif info_type == 'Picture': # 保存圖片 info(temp + '/' + name) itchat.run() 

運行起來,然后發送一張圖片和一條語音,就會在指定目錄下生成兩個文件:
在這里插入圖片描述

如何監聽好友撤回了消息

到這里,我們其實已經完成了消息監聽,只需要稍加修改即可,但是這個程序是有缺陷的,因為不是所有消息我們都需要去保存的,好友正常發送過來的消息我們直接就能看到,保存下來不是多此一舉嗎?我們的目的是想知道好友撤回了什么內容,這就涉及到如何監聽好友是否撤回了消息這一問題了。其實也非常簡單,Content模塊為我們提供了NOTE類型,該類型指的是系統消息。

所以我們可以自定義一個函數用來監聽系統消息:

import itchat from itchat.content import * # 導入itchat下的content模塊 itchat.auto_login(hotReload=True) @itchat.msg_register(NOTE) def note_info(msg): # 監聽系統消息 print(msg) itchat.run() 

運行程序,我們撤回一條消息測試一下,輸出結果如下:

...... 'DisplayName': '', 'ChatRoomId': 0, 'KeyWord': '', 'EncryChatRoomId': '', 'IsOwner': 0}>, 'Type': 'Note', 'Text': '你撤回了一條消息'} ...... 

這里截取了部分內容,會發現,撤回消息的文本內容為"你撤回了一條消息",所以要想知道好友是否撤回了消息就非常簡單了,判斷msg['Text'] == '你撤回了一條消息'即可。

實現微信防撤回程序

關於程序每個步驟的代碼到這里就分析完了,接下來是對所有代碼的匯總,也是整個程序的完整代碼:

import itchat from itchat.content import * import os import time import xml.dom.minidom # 解析xml模塊 # 這是保存撤回消息的文件目錄(如:圖片、語音等),這里已經寫死了,大家可以自行修改 temp = 'C:/Users/Administrator/Desktop/CrawlerDemo' + '/' + '撤回的消息' if not os.path.exists(temp): os.mkdir(temp) itchat.auto_login(True) # 自動登錄 dict = {} # 定義一個字典 # 這是一個裝飾器,給下面的函數添加新功能 # 能夠捕獲好友發送的消息,並傳遞給函數參數msg @itchat.msg_register([TEXT, PICTURE, FRIENDS, CARD, MAP, SHARING, RECORDING, ATTACHMENT, VIDEO]) # 文本,語音,圖片 def resever_info(msg): global dict # 聲明全局變量 info = msg['Text'] # 取出消息內容 msgId = msg['MsgId'] # 取出消息標識 info_type = msg['Type'] # 取出消息類型 name = msg['FileName'] # 取出消息文件名 # 取出消息發送者標識並從好友列表中檢索 fromUser = itchat.search_friends(userName=msg['FromUserName'])['NickName'] ticks = msg['CreateTime'] # 獲取信息發送的時間 time_local = time.localtime(ticks) dt = time.strftime("%Y-%m-%d %H:%M:%S", time_local) # 格式化日期 # 將消息標識和消息內容添加到字典 # 每一條消息的唯一標識作為鍵,消息的具體信息作為值,也是一個字典 dict[msgId] = {"info": info, "info_type": info_type, "name": name, "fromUser": fromUser, "dt": dt} @itchat.msg_register(NOTE) # 監聽系統提示 def note_info(msg): # 監聽到好友撤回了一條消息 if '撤回了一條消息' in msg['Text']: # 獲取系統消息中的Content結點值 content = msg['Content'] # Content值為xml,解析xml doc = xml.dom.minidom.parseString(content) # 取出msgid標簽的值 result = doc.getElementsByTagName("msgid") # 該msgId就是撤回的消息標識,通過它可以在字典中找到撤回的消息信息 msgId = result[0].childNodes[0].nodeValue # 從字典中取出對應消息標識的消息類型 msg_type = dict[msgId]['info_type'] if msg_type == 'Recording': # 撤回的消息為語音 recording_info = dict[msgId]['info'] # 取出消息標識對應的消息內容 info_name = dict[msgId]['name'] # 取出消息文件名 fromUser = dict[msgId]['fromUser'] # 取出發送者 dt = dict[msgId]['dt'] # 取出發送時間 recording_info(temp + '/' + info_name) # 保存語音 # 拼接提示消息 send_msg = '【發送人:】' + fromUser + '\n' + '發送時間:' + dt + '\n' + '撤回了一條語音' itchat.send(send_msg, 'filehelper') # 將提示消息發送給文件助手 # 發送保存的語音 itchat.send_file(temp + '/' + info_name, 'filehelper') del dict[msgId] # 刪除字典中對應的消息 print("保存語音") elif msg_type == 'Text': text_info = dict[msgId]['info'] # 取出消息標識對應的消息內容 fromUser = dict[msgId]['fromUser'] # 取出發送者 dt = dict[msgId]['dt'] # 取出發送時間 # 拼接提示消息 send_msg = '【發送人:】' + fromUser + '\n' + '發送時間:' + dt + '\n' + '撤回內容:' + text_info # 將提示消息發送給文件助手 itchat.send(send_msg, 'filehelper') del dict[msgId] # 刪除字典中對應的消息 print("保存文本") elif msg_type == 'Picture': picture_info = dict[msgId]['info'] # 取出消息標識對應的消息內容 fromUser = dict[msgId]['fromUser'] # 取出發送者 dt = dict[msgId]['dt'] # 取出發送時間 info_name = dict[msgId]['name'] # 取出文件名 picture_info(temp + '/' + info_name) # 保存圖片 # 拼接提示消息 send_msg = '【發送人:】' + fromUser + '\n' + '發送時間:' + dt + '\n' + '撤回了一張圖片' itchat.send(send_msg, 'filehelper') # 將圖片發送給文件助手 # 發送保存的語音 itchat.send_file(temp + '/' + info_name, 'filehelper') del dict[msgId] # 刪除字典中對應的消息 print("保存圖片") itchat.run(

這樣,一個完整的防撤回程序就完成了,如果你對於前面的鋪墊能夠掌握得很好的話,這個程序對你來說就是小菜一碟,每一句代碼的注釋我都有寫,應該很容易看懂。

測試程序

到了激動人心的測試環節,我們來測試一下這個程序是否編寫成功了。

在這里插入圖片描述

我向我的好友發送了三條消息,分別是文本、圖片和語音,接着我一一撤回,然后,微信程序就自動向文件傳輸助手發送了三條消息:
在這里插入圖片描述

到這里,這個程序就基本完成了。你們在測試的時候也可以叫自己的好友、同學發給你幾條消息,然后撤回看看是否能夠成功獲取到撤回的消息。

撤回的消息發給別人肯定不行,這樣不僅泄露了隱私,也會騷擾到別人,所以這里我選擇將撤回的消息發送給文件傳輸助手,如何將消息發送給文件傳輸助手也很簡單:

itchat.send(send_msg, toUserName='filehelper') 
  • 1
  • 2

toUserName傳入filehelper即可,這樣,如果對方撤回了消息,你就可以前往文件傳輸助手查看對方究竟撤回了什么。

說說我遇到的一些坑

這個程序說它難,其實並不難,但我也在編寫的過程中遇到了一些坑,一開始我是一條消息一條消息地進行測試,發現程序是正常的,但我連續撤回幾條消息,卻發現程序出現了Bug。比如我一開始發送了一張圖片和一段文字,結果我撤回這兩條消息后,得到的卻是兩段文字。后面我才醒悟過來,是后面的消息覆蓋了前面的消息,導致了這個結果,所以在程序中,我定義了一個字典,用於存放好友輸入的消息,當監聽到消息被撤回時,就通過撤回消息產生的內容中的msgId去和字典中的匹配,匹配到的就是被撤回的消息,然后進行操作即可。

使用教程

想使用該程序非常簡單,實現微信防撤回程序節點下有程序的完整代碼,直接復制粘貼到你自己的python文件,然后運行該文件即可,運行后會產生一個二維碼,用手機驗證登錄即可。
當然,你也可以選擇將該程序打包成可執行的exe文件,這樣運行更加方便,打包方式:
首先打開cmd窗口,下載pyinstaller模塊,有的話就不用下載了,下載指令:pip insall pyinstaller,此時我們通過cmd窗口進入到python文件目錄,比如我這里
在這里插入圖片描述
那就進入到該目錄下:
在這里插入圖片描述
然后執行下面這條指令:

pyinstaller -F wechat.py
  • 1

后面是需要打包的文件名,執行命令后,就會在文件同級目錄下生成一個dist文件夾。
在這里插入圖片描述
進入該文件夾,就看到我們的.exe文件了,然后雙擊執行即可。

最后

這個程序目前只實現了監聽好友的文本、圖片、語音類型的消息,對於其它類型的消息,還有群聊的消息都是無法監聽到的,感興趣的話大家可以自己試着實現一下。也可以去小編的Python交流.裙 :一久武其而而流一思(數字的諧音)轉換下可以找到了,里面有最新Python教程項目,多跟他們交流,你會進步很快!

因為自己也是剛剛接觸這個模塊,文中的程序可能會出現一些意想不到的Bug,但目前我測試來看是沒有問題的,如有問題,歡迎評論區留言。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM