前言
上篇文章(Python微信机器人) 批量检测单向好友(对方无感知))说了怎么检测好友是否把你删除或拉黑,这篇文章说一下怎么备份全部的好友列表,方便到时候误删某个好友时加回来,顺便补充一个检测单向好友的方法。
机器人文件获取(两个月试用,按月收费):https://github.com/kanadeblisst00/pywxrobot
补充
写这篇文章的时候意外发现一个可以用来检测单向好友的方法(对方也是无感知):通过从网络获取好友信息这个功能。是不是好友获取到的信息有个字段不一样,不过目前还没有经过多人测试,不确定这样判断是否准确。
有兴趣并且想测试的可以看最下面备份完整信息
的代码,里面有个字段好友
就表示是否是好友。
目前还无法直接区分是被删除了还是被拉黑了,被删除和被拉黑返回的字段内容虽然有些不一样(被拉黑的话字段会少一些),但是如果好友没有设置这些字段那返回的都是一样的,所以会存在误判。不过正常来说,头像肯定是设置了的,通过头像是否存在判断的话结果基本可信。
其实你可以先保存一遍好友的信息,下次检测的时候如果发现不是好友,就看一下之前保存的信息里是不是有这些字段(头像),然后再看现在能不能获取到这些字段,如果不一样说明是被拉黑,否则是被删除。
备份
其实上篇检测好友列表就用到了这个函数,功能函数: def GetContactList() -> dict:
备份好友列表
需要的Python脚本如下,已经作为插件放到了pyrobot\other_plugins\export_friends.py
。
import os
import wxfunc
from typing import List
def main():
print("开始导出好友列表!")
keys = ("wxid", "微信号", "备注", "头像", "小头像", "昵称", "地区", "省份", "城市", "描述")
contacts:List[dict] = dict(wxfunc.GetContactList())["friend"]
path = os.path.abspath("好友列表.csv")
with open(path, 'w', encoding='utf-8') as f:
f.write(','.join(keys) + "\n")
for contact in contacts:
line = ','.join([contact.get(key, "") for key in keys]) + '\n'
f.write(line)
print(f"导出好友列表完成, csv文件路径: {path}!")
if __name__ == "__main__":
main()
运行pywxrobot pyrobot\other_plugins\export_friends.py
等待一两秒就能看到有个好友列表.csv
生成了。
备份群列表
import os
import wxfunc
from typing import List
def main():
print("开始导出群列表!")
keys = ("wxid", "微信号", "备注", "头像", "小头像", "昵称", "地区", "省份", "城市", "描述")
contacts:List[dict] = dict(wxfunc.GetContactList())["chatroom"]
path = os.path.abspath("群列表.csv")
with open(path, 'w', encoding='utf-8') as f:
f.write(','.join(keys) + "\n")
for contact in contacts:
line = ','.join([contact.get(key, "") for key in keys]) + '\n'
f.write(line)
print(f"导出群列表完成, csv文件路径: {path}!")
if __name__ == "__main__":
main()
代码所在目录: pyrobot\other_plugins\export_rooms.py
备份公众号列表
import os
import wxfunc
from typing import List
def main():
print("开始导出公众号列表!")
keys = ("wxid", "微信号", "备注", "头像", "小头像", "昵称", "地区", "省份", "城市", "描述")
contacts:List[dict] = dict(wxfunc.GetContactList())["biz"]
path = os.path.abspath("公众号列表.csv")
with open(path, 'w', encoding='utf-8') as f:
f.write(','.join(keys) + "\n")
for contact in contacts:
line = ','.join([contact.get(key, "") for key in keys]) + '\n'
f.write(line)
print(f"导出公众号列表完成, csv文件路径: {path}!")
if __name__ == "__main__":
main()
代码所在目录: pyrobot\other_plugins\export_bizs.py
优化
这样导出来的列表会缺少很多字段,基本只有wxid
、微信号和昵称这三个字段。如果需要更多的字段信息,例如头像、性别这些,则需要从网络重新获取一遍。
用到的功能函数: def GetUserInfoByNet(wxid:str) -> dict:
,这个函数功能比较多,除了获取好友信息,还能获取到包含昵称的群成员列表,后面有人需要的话再详细说。
简单获取单个好友信息
import wxfunc
info = wxfunc.GetUserInfoByNet("wxid_mp7earq22qtg22")
print(info)
将测试脚本保存为test.py
,然后使用pywxrobot.exe pyrobot\test.py
这里我获取的是我自己的信息,如果是好友的话还有些其他字段,例如城市这些。因为是直接解析的pb,没有对应的proto文件,有些字段不知道是啥含义无法解析出来,所以我只解析了我知道的一些字段。
如果你想获取我没有解析出来的字段,第二个参数传1可以让它返回原始pb的json数据,然后你自己来解析它:info = wxfunc.GetUserInfoByNet("wxid_mp7earq22qtg22", 1)
。
想知道字段是哪个,某个值代表什么意思,先找个小号修改这个字段重复调用这个函数获取到信息,在对比修改前后值有什么不一样。
备份完整信息
完整代码放在pyrobot\other_plugins\export_total_friends_info.py
import os
import wxfunc
import time
from typing import List
def main():
print("开始导出好友列表!")
keys = ("wxid", "微信号", "备注", "头像", "小头像", "昵称", "地区", "省份", "城市", "描述", "性别", "好友")
contacts:List[dict] = dict(wxfunc.GetContactList())["friend"]
path = os.path.abspath("完整好友列表.csv")
with open(path, 'w', encoding='utf-8') as f:
f.write(','.join(keys) + "\n")
for contact in contacts:
info = wxfunc.GetUserInfoByNet(contact["wxid"])
line = ','.join([(contact.get(key) or info.get(key, "")).replace(",", "_").replace("\n", " ") for key in keys]) + '\n'
print(line)
f.write(line)
time.sleep(2)
print(f"导出好友列表完成, csv文件路径: {path}!")
if __name__ == "__main__":
main()
生成的文件筛选最后一项就能看到哪些不是好友,能获取到头像说明都是被删除的,不是被拉黑:
注意:如果好友有四五千个,这个方案不一定能一天测试完成,目前只测试了一千多次。