C#模拟登录微信公众平台实现群发消息技术解析

花开有时
花开有时
发布时间:2026-10-14 | 5人浏览过
原创

通过C#模拟登录微信公众平台管理后台,利用HttpWebRequest抓取会话令牌(Token)与Cookie,进而实现对关注者的消息推送。该方案的核心在于模拟浏览器行为完成身份验证并解析页面数据以获取用户唯一标识(fakeId),适用于特定场景下的自动化测试或历史项目维护,但请注意官方平台对第三方模拟行为的限制。

技术实现原理

要实现非官方的消息推送功能,核心逻辑是通过程序模拟浏览器对网页版微信公众平台(mp.weixin.qq.com)进行HTTP请求。整个过程主要分为两个阶段:首先建立会话,即通过账户密码获取服务器的Session凭证;其次是业务操作,即携带这些凭证请求具体的数据接口。

  1. 账号准备:需要拥有一个已认证或正常运行的微信公众号管理员账号。
  2. 模拟登录:向登录接口发起POST请求,传输经过处理的用户名和密码,服务器返回包含令牌的JSON数据及Set-Cookie信息。
  3. 数据解析:在登录状态下访问好友列表页,解析HTML源码提取每个用户的fakeId,这是发送消息的必要参数。
  4. 消息发送:携带之前获得的Cookie和Token,向单发消息接口发送POST请求,将内容发送给目标fakeId。

环境与安全准备

在进行此类开发前,需明确以下前提:
1. 代码依赖 .NET Framework 中的 System.Net 和 System.Web 命名空间。
2. 建议使用 Newtonsoft.Json 库处理JSON序列化。
3. 风险提示:微信官方严禁使用非授权工具进行批量操作或使用脚本登录。此方法仅用于技术学习或特定内部测试,大规模使用可能导致公众号被限制功能或封禁。建议在使用前备份账号安全设置,避免敏感信息泄露。

第一步:实现模拟登录功能

登录是获取后续操作权限的关键。我们需要构造一个POST请求发送到微信的登录API,并对密码进行特定的加密处理。

1. 密码MD5加密处理

微信登录接口要求密码必须经过MD5加密且转换为大写。以下是标准的C# MD5加密实现:

static string GetMd5Str32(string str)
{
    MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
    char[] temp = str.ToCharArray();
    byte[] buf = new byte[temp.Length];
    for (int i = 0; i < temp.Length; i++)
    {
        buf[i] = (byte)temp[i];
    }
    byte[] data = md5Hasher.ComputeHash(buf);
    StringBuilder sBuilder = new StringBuilder();
    for (int i = 0; i < data.Length; i++)
    {
        sBuilder.Append(data[i].ToString("x2"));
    }
    return sBuilder.ToString().ToUpper();
}

2. 执行登录请求

使用 HttpWebRequest 发起登录请求。注意URL中的路径及参数格式,确保使用UTF-8编码。

public static bool ExecLogin(string name, string pass)
{
    bool result = false;
    // 获取加密后的密码
    string password = GetMd5Str32(pass).ToUpper();
    // 构造POST数据
    string padata = "username=" + name + "&pwd=" + password + "&imgcode=&f=json";
    // 登录接口地址
    string url = "http://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN";

    try
    {
        CookieContainer cc = new CookieContainer();
        byte[] byteArray = Encoding.UTF8.GetBytes(padata);
        HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(url);
        
        webRequest2.CookieContainer = cc;
        webRequest2.Method = "POST";
        webRequest2.ContentType = "application/x-www-form-urlencoded";
        webRequest2.ContentLength = byteArray.Length;
        
        Stream newStream = webRequest2.GetRequestStream();
        newStream.Write(byteArray, 0, byteArray.Length);
        newStream.Close();

        HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
        StreamReader sr2 = new StreamReader(response2.GetResponseStream(), Encoding.Default);
        string text2 = sr2.ReadToEnd();

        // 反序列化JSON响应
        WeiXinRetInfo retinfo = Newtonsoft.Json.JsonConvert.DeserializeObject<WeiXinRetInfo>(text2);
        
        if (!string.IsNullOrEmpty(retinfo.ErrMsg))
        {
            // 从错误消息中提取token(格式通常为 error=xxx&token=xxx&r=xxx)
            string token = retinfo.ErrMsg.Split(new char[] { '&' })[2].Split(new char[] { '=' })[1];
            
            // 保存状态
            LoginInfo.LoginCookie = cc;
            LoginInfo.CreateDate = DateTime.Now;
            LoginInfo.Token = token;
            result = true;
        }
    }
    catch (Exception ex)
    {
        throw new Exception(ex.StackTrace);
    }
    return result;
}

public static class LoginInfo
{
    public static string Token { get; set; }
    public static CookieContainer LoginCookie { get; set; }
    public static DateTime CreateDate { get; set; }
}

第二步:获取用户fakeId

在微信后台体系内,直接显示的名称不是发送消息的目标ID,而是隐藏在页面源码中的 fakeId。因此,我们需要在登录后访问好友管理页面,并解析HTML内容。

public static ArrayList SubscribeMP()
{
    try
    {
        // 获取全局登录状态
        CookieContainer cookie = LoginInfo.LoginCookie;
        string token = LoginInfo.Token;

        // 访问好友列表页
        string Url = $"https://mp.weixin.qq.com/cgi-bin/contactmanagepage?t=wxm-friend&token={token}&lang=zh_CN&pagesize=10&pageidx=0&type=0&groupid=0";
        HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(Url);
        webRequest2.CookieContainer = cookie;
        webRequest2.Method = "GET";
        webRequest2.UserAgent = "Mozilla/5.0 (Windows NT 5.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1";

        HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
        StreamReader sr2 = new StreamReader(response2.GetResponseStream(), Encoding.Default);
        string text2 = sr2.ReadToEnd();

        // 使用正则表达式提取fakeId
        // 注意:正则表达式需根据实际前端结构进行调整
        Regex r = new Regex(@"""fakeId\"\\\:s\:\""\d+""");
        MatchCollection mc = r.Matches(text2);
        
        ArrayList fackIDList = new ArrayList();
        foreach (Match item in mc)
        {
            string fakeID = item.Value.Split(new char[] { ':' })[1];
            fakeID = fakeID.Replace("\"", "").Trim();
            fackIDList.Add(fakeID);
        }
        return fackIDList;
    }
    catch (Exception ex)
    {
        throw new Exception(ex.StackTrace);
    }
}
注意:上述正则表达式仅为示例结构。由于微信前端代码会不定期更新,HTML结构变化会导致正则匹配失败。实际使用时需在浏览器开发者工具中检查当前页面的真实DOM结构,调整Regex模式。

第三步:发送单条消息

拥有 cookie、token 和目标用户的 fakeId 后,即可调用单发接口发送文本消息。该接口通常用于测试连通性或小范围通知。

public static bool SendMessage(string message, string fakeid)
{
    bool result = false;
    string token = LoginInfo.Token;
    CookieContainer cookie = LoginInfo.LoginCookie;

    // URL编码消息内容
    string strMsg = System.Web.HttpUtility.UrlEncode(message);
    
    // 构造发送接口参数
    string padate = $"type=1&content={strMsg}&error=false&tofakeid={fakeid}&token={token}&ajax=1";
    string url = "https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response&lang=zh_CN";

    try
    {
        byte[] byteArray = Encoding.UTF8.GetBytes(padate);
        HttpWebRequest webRequest2 = (HttpWebRequest)WebRequest.Create(url);
        
        webRequest2.CookieContainer = cookie;
        // 必须设置Referer,否则可能被拦截
        webRequest2.Referer = $"https://mp.weixin.qq.com/cgi-bin/singlemsgpage?token={token}&fromfakeid={fakeid}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN";
        webRequest2.Method = "POST";
        webRequest2.ContentType = "application/x-www-form-urlencoded";
        webRequest2.ContentLength = byteArray.Length;

        Stream newStream = webRequest2.GetRequestStream();
        newStream.Write(byteArray, 0, byteArray.Length);
        newStream.Close();

        HttpWebResponse response2 = (HttpWebResponse)webRequest2.GetResponse();
        StreamReader sr2 = new StreamReader(response2.GetResponseStream(), Encoding.Default);
        string text2 = sr2.ReadToEnd();

        if (text2.Contains("ok"))
        {
            result = true;
        }
    }
    catch (Exception)
    {
        result = false;
    }
    return result;
}

完成判断与排错

成功标志:
1. 登录步骤返回 true 且 LoginInfo.Token 不为空。
2. SubscribeMP() 方法能正确解析出fakeId数组。
3. SendMessage 返回值 true,且服务端响应中包含 "ok"。

常见异常排查:
- 403 Forbidden:通常是因为缺少 Referer 头或Cookie过期,请确保每次请求都携带完整的Cookie容器,并按顺序调用各接口保持会话。
- 登录失败/验证码:如果频繁尝试登录,微信可能会要求输入验证码。代码中预留了 imgcode 字段,实际使用中可能需要集成验证码识别服务或暂停请求等待人工干预。
- 正则匹配为空:说明页面结构已变。请按F12打开浏览器控制台,重新查看 contactmanagepage 返回的HTML中fakeId的实际表现形式,更新正则表达式。

简要总结

通过C#的HttpWebRequest模拟登录微信网页版,可以实现获取Token、解析用户FakeID以及发送消息的完整链路。该方法展示了基于HTTP协议的应用层交互原理。然而,鉴于微信公众平台接口的严格管控及防爬机制升级,此类非官方手段具有不稳定性,不建议在生产环境中作为核心业务依赖,仅供技术研究参考。

以上就是C#模拟登录微信公众平台实现群发消息的详细内容,更多关于C#网络编程的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表