微信好友越来越多,奈何微信一直没有出和QQ一样的功能,即:删除本地好友的同时也一并删除对方好友列表中的自己。于是,你也不知道呆在你自己微信好友列表中的好友是不是还是你的好友。经常时不时的收到多年未联系的好友信息:“正在清理好友”。一般发来这种的都是网上花几块钱买的服务,需要扫一个服务商提供的二维码,让自己微信在他们“特殊的微信客户端”登录,然后执行清理好友脚本服务。但是这种把自己微信交给别人的感觉实在是太危险了。于是,这篇文章的灵感诞生了。

提前说一下:此脚本因为是实时操作,所以挺费时间的。

教学视频

清理微信僵尸好友的几个方法

第一:发起群聊

创建一个群聊,把需要检测的好友都拉入群聊,当对方不是你的好友系统会提示“无法邀请非好友进入群聊”。这种方式需要注意,如果群聊人数超过四十人,好友可能会收到邀请进群的消息,所以如果你达做到不打扰的效果,注意人数总量控制在一定数量(建议少一点,比如30个)。如果在群里不发消息,他们是收不到提示信息的。

第二:私发一条消息

这种应该是最直接的办法,提示:“你不是对方好友,请发送好友验证信息”说明对方删除你了。
提示:“消息已发出,但被对方拒收”,对方把你加入黑名单(对方不在收到你的消息,并且互相看不到对方朋友圈)
唯一的缺点就是对方会收到你的消息,会有点莫名其妙,甚至尴尬。可以考虑趁过节的时候发一下祝福,就当检测了。需要一个发送消息。
注意:使用微信的群发功能无法检测对方是否删除你。

方法三:先删除后加回来

先把微信号记下来,然后删除掉,第三步再添加回来,如果对方已经删除你,就会会提示需要对方验证。对方没有删除你,那么可以直接添加成功,而且对方无提示。

方法四:转账

给好友转账的3个步骤:
转账 -> 输入金额 -> 点击转账 -> 提示输入密码(停到这步不要输入支付密码)
如果对方已经删除你,那么在第3步的时候会弹出一个提示框“你不是对方收款好友”。
这样也能达到检测好友删除的目的。

脚本自动化实现原理

基本上,如果是脚本自动化,那么一般是利用的方法四,网上那种速度特别快就能监测完所有好友的工具,都是通过逆向微信客户端,重新封装了微信客户端的API,然后自动化操作。比如你可以搜索下:“微信iPad协议源码”。而我们所使用的方法就比较简单粗暴了。就是让机器模拟人类,给所有好友依次转账,一步一步的操作,点开好友,点击转账,查看信息。虽然慢,但是毕竟安全。

Airtest 移动端自动化

关于 Airtest 就不多说了,之前也有讲过,关于安装和配置,请参考:用 AirTest 实现手机APP自动签到领积分

获取好友列表

首先需要获得微信中所有的好友列表,这里我们直接进入通讯录,然后一页一页往上拉,直到最后,将所有好友放到列表中

def get_friend_list():
    friend_list = []
    while not poco("com.tencent.mm:id/ba5").exists():
        obj_list = poco("com.tencent.mm:id/ft6")
        for i in obj_list:
            friend_list.append(i.attr('text'))
        obj_list[-1].drag_to(obj_list[0])
    return set(friend_list)

单纯的只想保存好友列表的话,可以保存在文件中

friend_list = get_friend_list()
with open("./friend_list.txt",'w',encoding="utf8") as f:
   for i in friend_list:
    f.write("{}\n".format(i))
print(friend_list)

通过转账确认好友是否删除了自己

如果自己被好友删除了,那么将好友添加在 delete_friend_list 列表中,所以需要先定义一个 delete_friend_list 空列表

delete_friend_list = []
def open_session(name):
    poco("com.tencent.mm:id/dtx").click()
    search_btn = poco("com.tencent.mm:id/dt5")
    search_btn.click()
    search_ipt = poco(text="搜索")
    search_ipt.setattr("text",name)
    sleep(1)
    friend_Obj = poco("com.tencent.mm:id/ir3")
    friend_Obj.click()
    more_btn = poco(desc="更多功能按钮,已折叠")
    more_btn.click()
    trans_money_btn = poco(text="转账")
    trans_money_btn.click()
    money_ipt = poco("com.tencent.mm:id/jf4")
    money_ipt.setattr("text",0.01)
    do_trans_money = poco(text="转账")
    do_trans_money.click()
    sleep(1)
    if not poco(desc="使用密码,按钮").exists():
        delete_friend_list.append(name)
        poco(text="知道了").click()
        back_btn = poco("com.tencent.mm:id/eh")  # 回到聊天窗口
        back_btn.click()
        back_btn.click()
        keyevent("BACK")
    else:
        poco(desc="关闭,按钮").click()
        back_btn = poco("com.tencent.mm:id/eh")  # 回到聊天窗口
        back_btn.click()
        back_btn.click()
        keyevent("BACK")

删除好友操作

之前的操作只是返回一个列表,告诉你谁把你给删了,之后就会退回微信主界面,如果想同时删除好友的话,那么把退回主界面的过程换成删除好友的函数即可。

def delete_friend():
    poco(desc="更多信息").click()
    poco("com.tencent.mm:id/h8t").click()
    poco(desc="更多信息").click()
    poco(desc="删除").click()
    poco("com.tencent.mm:id/ffp").click()
    poco("com.tencent.mm:id/dtx").click()

main 函数

def main():
    # 测试代码
    # friend_list = ['好友A', '好友B']
    friend_list = get_friend_list()
    print(friend_list)
    for friend in friend_list:
        open_session(friend)
    print(delete_friend_list)

完整代码

# -*- encoding=utf8 -*-
__author__ = "Forece"

from airtest.core.api import *

auto_setup(__file__)

from poco.drivers.android.uiautomation import AndroidUiautomationPoco
poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)

delete_friend_list = []

def get_friend_list():
    friend_list = []
    while not poco("com.tencent.mm:id/ba5").exists():
        obj_list = poco("com.tencent.mm:id/ft6")
        for i in obj_list:
            friend_list.append(i.attr('text'))
        obj_list[-1].drag_to(obj_list[0])
    return set(friend_list)

def open_session(name):
    search_btn = poco("com.tencent.mm:id/dt5")
    search_btn.click()
    search_ipt = poco(text="搜索")
    search_ipt.setattr("text",name)
    sleep(1)
    friend_Obj = poco("com.tencent.mm:id/ir3")
    friend_Obj.click()
    more_btn = poco(desc="更多功能按钮,已折叠")
    more_btn.click()
    trans_money_btn = poco(text="转账")
    trans_money_btn.click()
    money_ipt = poco("com.tencent.mm:id/jf4")
    money_ipt.setattr("text",0.01)
    do_trans_money = poco(text="转账")
    do_trans_money.click()
    if not poco(desc="使用密码,按钮").exists():
        delete_friend_list.append(name)
        poco(text="知道了").click()
        back_btn = poco("com.tencent.mm:id/eh")  # 回到聊天窗口
        delete_friend()
    else:
        poco(desc="关闭,按钮").click()
        back_btn = poco("com.tencent.mm:id/eh")  # 回到聊天窗口
        back_btn.click()
        back_btn.click()
        keyevent("BACK")

def delete_friend():
    poco(desc="更多信息").click()
    poco("com.tencent.mm:id/h8t").click()
    poco(desc="更多信息").click()
    poco(desc="删除").click()
    poco("com.tencent.mm:id/ffp").click()
    poco("com.tencent.mm:id/dtx").click()

        
def main():
    # 测试代码
    # friend_list = ['好友A', '好友B']
    friend_list = get_friend_list()
    print(friend_list)
    for friend in friend_list:
        try:
            open_session(friend)
        except:
            continue
    print(delete_friend_list)

if __name__ == '__main__':
    main()