首页 / 博客 / API·多语言·接口

微信API获取好友列表与群列表实战

分类:API·多语言·接口 · 标签:微信API、通讯录、好友列表

前言

在开发微信自动化工具或企业内部运营系统时,获取好友列表与群列表是绕不开的基础能力。无论是做 CRM 数据同步、批量消息分发,还是构建私域流量管理后台,第一步往往都是"先把通讯录摸清楚"——哪些好友在列表里、哪些群需要维护、群成员结构如何。

然而,微信本身并不对外提供官方开放 API,常见的做法是借助托管式 HTTP 接口服务,通过扫码登录后,用 REST 调用来完成联系人和群的增删查改操作。本文将系统介绍这套流程的实现思路,包括:扫码登录获取设备 ID(appId)、拉取好友通讯录、获取群列表、查询群成员,并给出完整的 Python 示例代码,以及实际使用时必须注意的频控和防封策略。


一、整体流程与核心概念

1.1 为什么需要 appId

托管式微信接口以"设备"为单位管理登录状态。每次扫码登录成功后,服务端会返回一个 appId,代表当前这台设备(一个微信账号的登录实例)。后续所有接口调用都必须带上这个 appId,以便服务端识别是哪个账号在操作。

一个账号只有一个在线 appId;如果在其他地方再次登录,原 appId 会失效,需要重新扫码。因此在实际项目中,建议把 appId 持久化到配置文件或数据库,并在每次启动时先校验其有效性,失效才触发重新扫码流程,避免每次启动都打断正常业务。

1.2 鉴权方式

所有接口统一使用 HTTP POST,请求体为 JSON,鉴权 Token 放在请求头中(字段名以官方文档为准,下文示例用 token 作占位)。

pythonBASE    = "https://你的接口域名"   # 注册后在官方文档获取
TOKEN   = "你的Token"
APPID   = "你的appId"              # 扫码登录后获得
HEADERS = {"token": TOKEN}         # 鉴权字段名以官方文档为准
注意:以上均为占位符,具体接口地址、Token 格式、字段名称均以官方文档为准。

1.3 统一返回格式

json{
  "ret": 200,
  "msg": "操作成功",
  "data": { ... }
}

ret == 200 表示成功,其他值表示异常,需根据 msg 字段排查原因。建议在封装请求函数时统一处理非 200 的情况,记录日志后再向上层抛异常,方便定位问题。


二、扫码登录流程

在拉取通讯录之前,必须先完成登录,拿到 appId

2.1 获取二维码

pythonimport requests
import json

def get_login_qrcode():
    url = f"{BASE}/login/getLoginQrCode"
    body = {}
    resp = requests.post(url, json=body, headers=HEADERS)
    data = resp.json()
    if data["ret"] == 200:
        qr_url = data["data"]["qrCodeUrl"]  # 字段名以官方文档为准
        print("请扫描二维码登录:", qr_url)
        return data["data"]
    else:
        raise Exception(f"获取二维码失败:{data['msg']}")

2.2 轮询登录状态

pythonimport time

def wait_for_login(wait_seconds=60, interval=3):
    """每隔 interval 秒查询一次登录状态,最多等待 wait_seconds 秒"""
    for _ in range(wait_seconds // interval):
        url = f"{BASE}/login/checkLogin"
        resp = requests.post(url, json={}, headers=HEADERS)
        data = resp.json()
        if data["ret"] == 200:
            app_id = data["data"]["appId"]
            print(f"登录成功,appId = {app_id}")
            return app_id
        time.sleep(interval)
    raise TimeoutError("登录超时,请重新获取二维码")

登录成功后,将 app_id 保存到配置或数据库,后续所有调用都复用它,无需反复扫码。

实操建议:二维码有效期通常在 1~3 分钟,过期后需重新调用获取接口。生产环境中可将二维码图片通过企业微信机器人或钉钉消息推送给运维人员扫码,避免每次都要登服务器操作。


三、获取好友列表

3.1 接口说明

拉取好友通讯录(fetchContactsList)返回的是账号下所有微信好友的列表,包含微信 ID(wxid)、昵称、备注名等基础信息。

参数类型说明
appIdstring设备 ID,登录后获取
pythondef fetch_contacts_list(app_id):
    url = f"{BASE}/contacts/fetchContactsList"
    body = {"appId": app_id}
    resp = requests.post(url, json=body, headers=HEADERS)
    data = resp.json()
    if data["ret"] == 200:
        contacts = data["data"]["contacts"]  # 字段名以官方文档为准
        print(f"共获取好友 {len(contacts)} 人")
        return contacts
    else:
        raise Exception(f"获取好友列表失败:{data['msg']}")

注意事项

3.2 获取单个好友详情

通讯录列表接口返回的字段较精简,若需要头像、地区、个性签名等详细信息,可再调用 getDetailInfo

pythondef get_contact_detail(app_id, wxid):
    url = f"{BASE}/contacts/getDetailInfo"
    body = {"appId": app_id, "wxids": [wxid]}  # 字段名以官方文档为准
    resp = requests.post(url, json=body, headers=HEADERS)
    data = resp.json()
    if data["ret"] == 200:
        return data["data"]
    else:
        raise Exception(f"获取好友详情失败:{data['msg']}")

该接口支持批量传入多个 wxid,批量查询时建议每批不超过 20 个,并在批次之间加入 2~5 秒随机延迟,以降低被触发风控的概率。

3.3 搜索联系人

如果只知道微信号或手机号,可以先用搜索接口查找:

pythondef search_contact(app_id, keyword):
    url = f"{BASE}/contacts/search"
    body = {"appId": app_id, "keyword": keyword}
    resp = requests.post(url, json=body, headers=HEADERS)
    data = resp.json()
    if data["ret"] == 200:
        return data["data"]
    else:
        raise Exception(f"搜索联系人失败:{data['msg']}")
搜索接口有频控,建议每天不超过 10~20 次,避免触发风控。

四、获取群列表与群成员

4.1 说明

托管接口对群(Chatroom)的操作通常与普通好友分开,群 ID(chatroomId)格式一般以 @chatroom 结尾,与普通微信 ID 有所区别。具体格式以接口返回值为准。

WechatApi 提供扫码登录、消息收发、好友与群管理等 REST 接口,HTTP 调用即可,群管理覆盖从创建、邀请、移除到公告设置的完整链路。

4.2 获取群列表

群列表一般也通过通讯录接口获取,服务端会在返回的联系人列表中区分普通好友与群聊,也可能提供单独的群列表接口(具体以官方文档为准)。

下面展示一种常见的通过过滤通讯录来区分好友与群的方式:

pythondef fetch_chatrooms_from_contacts(app_id):
    contacts = fetch_contacts_list(app_id)
    chatrooms = [c for c in contacts if c.get("wxid", "").endswith("@chatroom")]
    friends   = [c for c in contacts if not c.get("wxid", "").endswith("@chatroom")]
    print(f"好友数量:{len(friends)},群数量:{len(chatrooms)}")
    return friends, chatrooms

实操细节

4.3 获取群成员列表

拿到群 ID 后,可调用 getChatroomMemberList 获取群内所有成员:

pythondef get_chatroom_member_list(app_id, chatroom_id):
    url = f"{BASE}/chatroom/getChatroomMemberList"
    body = {"appId": app_id, "chatroomId": chatroom_id}
    resp = requests.post(url, json=body, headers=HEADERS)
    data = resp.json()
    if data["ret"] == 200:
        members = data["data"]["members"]  # 字段名以官方文档为准
        print(f"群 {chatroom_id} 共有成员 {len(members)} 人")
        return members
    else:
        raise Exception(f"获取群成员失败:{data['msg']}")

注意:对于成员数超过 500 人的大群,接口返回的数据量较大,建议分页或流式处理,避免一次性加载导致内存压力。同时,大群成员列表变动频繁,若需要实时追踪成员变化(如新人入群、退群),建议结合消息回调机制,而非高频轮询该接口。

4.4 获取群二维码

pythondef get_chatroom_qrcode(app_id, chatroom_id):
    url = f"{BASE}/chatroom/getChatroomQrCode"
    body = {"appId": app_id, "chatroomId": chatroom_id}
    resp = requests.post(url, json=body, headers=HEADERS)
    data = resp.json()
    if data["ret"] == 200:
        return data["data"]
    else:
        raise Exception(f"获取群二维码失败:{data['msg']}")

群二维码有有效期限制(通常 7 天),过期后需重新调用本接口刷新。如果业务需要长期有效的入群链接,建议定期更新并将新二维码同步到投放渠道。


五、通讯录数据的实用场景

5.1 同步到本地数据库

将好友列表定期同步到 MySQL/SQLite,便于后续做标签管理、消息定向推送:

pythonimport sqlite3

def sync_contacts_to_db(contacts, db_path="contacts.db"):
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    cursor.execute("""
        CREATE TABLE IF NOT EXISTS contacts (
            wxid TEXT PRIMARY KEY,
            nickname TEXT,
            remark TEXT,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
    """)
    for c in contacts:
        cursor.execute("""
            INSERT OR REPLACE INTO contacts (wxid, nickname, remark)
            VALUES (?, ?, ?)
        """, (
            c.get("wxid", ""),
            c.get("nickname", ""),
            c.get("remark", "")   # 字段名以官方文档为准
        ))
    conn.commit()
    conn.close()
    print(f"已同步 {len(contacts)} 条联系人数据到数据库")

同步时推荐使用 INSERT OR REPLACE(SQLite)或 INSERT ... ON DUPLICATE KEY UPDATE(MySQL),以幂等方式更新数据,避免重复同步时产生重复记录。同步任务可配合定时任务(如 cron)每天低峰期执行一次全量刷新。

5.2 批量发消息前的通讯录校验

发消息前先校验目标 wxid 是否在好友列表中,可以减少无效调用,降低被封风险:

pythondef filter_valid_wxids(app_id, target_wxids):
    contacts = fetch_contacts_list(app_id)
    valid_set = {c["wxid"] for c in contacts}
    valid     = [wxid for wxid in target_wxids if wxid in valid_set]
    invalid   = [wxid for wxid in target_wxids if wxid not in valid_set]
    print(f"有效 {len(valid)} 个,无效(非好友){len(invalid)} 个")
    return valid, invalid

将无效 wxid 单独记录下来,可作为后续加好友或核查数据的依据,避免反复对非好友发送消息请求,白白消耗接口调用次数。


六、频控与风险控制

微信对自动化操作非常敏感,通讯录相关接口尤其需要注意以下几点:

6.1 好友列表拉取频率

操作建议频率
拉取好友列表每次业务需要时拉取,不建议高频轮询,可本地缓存
搜索联系人≤ 10~20 次/天
获取单个好友详情按需调用,批量时加随机间隔 3~10s

6.2 群操作频率

操作建议频率
获取群成员列表按需调用,缓存结果,非必要不重复拉
创建群聊≤ 10 个/天,间隔 10 分钟以上
邀请/移除成员小批量操作,加随机间隔

6.3 新账号注意事项

6.4 常见错误排查

现象可能原因
ret 非 200,提示频率限制调用过于频繁,需降低速率
通讯录返回为空账号未完全同步,等待几分钟后重试
登录状态丢失微信在其他设备上被强制下线,需重新扫码
搜索无结果对方设置了隐私,或微信号/手机号有误
获取群成员超时群成员数量过多,适当增大请求超时时间

七、完整示例:一键导出好友与群信息

下面把前面的模块拼在一起,展示一个完整的"登录 → 拉通讯录 → 分类 → 导出 JSON"的流程:

pythonimport requests
import json
import time

BASE    = "https://你的接口域名"   # 注册后在官方文档获取
TOKEN   = "你的Token"
HEADERS = {"token": TOKEN}

def main():
    # Step 1: 获取二维码
    qr_data = get_login_qrcode()
    print("二维码已生成,请扫码:", qr_data.get("qrCodeUrl"))

    # Step 2: 等待登录
    app_id = wait_for_login(wait_seconds=90, interval=3)

    # Step 3: 拉取通讯录
    contacts = fetch_contacts_list(app_id)

    # Step 4: 分类
    friends   = [c for c in contacts if not c.get("wxid", "").endswith("@chatroom")]
    chatrooms = [c for c in contacts if c.get("wxid", "").endswith("@chatroom")]

    # Step 5: 导出
    result = {
        "appId": app_id,
        "friendCount": len(friends),
        "chatroomCount": len(chatrooms),
        "friends": friends,
        "chatrooms": chatrooms
    }
    with open("contacts_export.json", "w", encoding="utf-8") as f:
        json.dump(result, f, ensure_ascii=False, indent=2)

    print(f"导出完成:好友 {len(friends)} 人,群 {len(chatrooms)} 个")

if __name__ == "__main__":
    main()
代码为示例,具体接口路径、请求字段、返回字段均以官方文档为准。

小结

本文梳理了通过托管式 HTTP 接口获取微信好友列表与群列表的完整流程,涵盖扫码登录、通讯录拉取、群成员查询、本地数据库同步以及频控策略。几个关键点值得再次强调:

通讯录数据是私域运营的基础底座,掌握好这些接口的正确用法,后续的消息推送、标签分组、群管理等功能才能稳定运行。

想动手试试?

WechatApi 提供扫码登录、消息收发、好友与群管理等 REST 接口,注册后几分钟跑通。

立即免费注册查看开发文档

相关产品页

🔗 微信机器人开发(产品页)🔗 微信群管理机器人(产品页)🔗 微信SCRM(产品页)

相关文章

微信API接口返回失败/收不到消息?完整排查清单微信 API 怎么对接?Python 发出第一条消息实战Node.js 微信机器人开发教程(发消息 + 收回调)个人微信API能力清单:消息/好友/群/朋友圈接口一览
© 2025 WechatApi · 企业级微信智能机器人接入平台
官网价格帮助文档博客
苏ICP备2024128799号 · 苏ICP备2023038368号