一.流程

1. //获得二维码的qrsig,cookie标志

2. //登录二维码获得二维码的状态,及最新的url

3. //登录此网址,获得Cookies

4.//cookies,筛选出skey信息,获得post的参数

5. 提交POST

二. 代码

/// <summary>
/// 获得QQ群返回的信息
/// </summary>
/// <returns></returns>
public string GetQQGroupMessage()
{
try
{
Random random = new Random();
var da = random.NextDouble();
string qrCodeUrl = @"https://ssl.ptlogin2.qq.com/ptqrshow?appid=715030901&e=2&l=M&s=3&d=72&v=4&t=" + da.ToString() + @"&daid=73&pt_3rd_aid=0";
string qqGroupCheckUrl = null;
string qqGroupNumberUrl = @"http://qun.qq.com/cgi-bin/qun_mgr/search_group_members";
string qrsig = null;
string setCookies = null;
string postData = null;
string responseMessage = null;
HTTPClient httpClient = new HTTPClient();

qrsig = httpClient.GetQRCode(qrCodeUrl); //获得二维码的qrsig,cookie标志

qqGroupCheckUrl = Login_QRStatu(httpClient, qrsig); //登录二维码获得二维码的状态,及最新的url

httpClient.Get(out setCookies, qqGroupCheckUrl); //登录此网址,获得Cookies

postData = GetPostData(setCookies); //cookies,筛选出skey信息,获得post的参数

responseMessage = httpClient.Post(qqGroupNumberUrl, postData);
LogHelp.LogDebug("Get QQ Group Message Success!");
return responseMessage;
}
catch (Exception ex)
{
LogHelp.LogDebug("Get QQ Group Message Failed!" + ex);
return null;
}
}

/// <summary>
/// 扫描二维码,并获得最新的url
/// </summary>
/// <param name="httpClient">
/// httpClient
/// </param>
/// <param name="qrsig">
/// qrsig
/// </param>
/// <returns></returns>
private string Login_QRStatu(HTTPClient httpClient,string qrsig)
{
int ptqrtoken = HTTPClient.HashConvert(qrsig);
string url = @"https://ssl.ptlogin2.qq.com/ptqrlogin?u1=https%3A%2F%2Fqun.qq.com%2F&ptqrtoken=" +
ptqrtoken.ToString() +
@"&ptredirect=1&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=0-1-1520572499521&js_ver=10233&js_type=1&login_sig=v-EnLBKGZcAOdXLgcH2k8Di6KrubBWgWZFpAo*KFmWVYbeWGCqLuQvlj4yanEo61&pt_uistyle=40&aid=715030901&daid=73&";
string referer = @"https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=715030901&daid=73&pt_no_auth=1&s_url=https%3A%2F%2Fqun.qq.com%2F";
string strLogionUrl = null;
string setCookies = null;
int timeCount = 0;
while (strLogionUrl == null)
{
timeCount++;
Thread.Sleep(1000);
string dat = httpClient.Get(out setCookies, url, referer);
string[] temp = dat.Split('\'');
switch (temp[1])
{

case ("65"):
LogHelp.LogDebug("当前登录状态:二维码失效,请稍后");
break;
case ("66"):
LogHelp.LogDebug("当前登录状态:二维码有效,请扫描");
break;
case ("67"):
LogHelp.LogDebug("当前登录状态:二维码已扫描,请确认");
break;
case ("0"):
LogHelp.LogDebug("当前登录状态:确认成功,请稍候");
strLogionUrl = temp[5];
break;
default:
LogHelp.LogDebug("登录信息有误,重新扫描!");
break;
}
if(timeCount>300) //5min内有效
{
break;
}
}
return strLogionUrl;
}

/// <summary>
/// post方法的参数
/// </summary>
/// <param name="setCookie">setCookies</param>
/// <returns></returns>
private string GetPostData(string setCookie)
{
try
{
string skey = HTTPClient.GetSkey(setCookie);
//string postData = "gc=621859311&st=0&end=800&sort=0&bkn=" + HTTPClient.GetBkn(skey).ToString();
string postData = KeyWordsLibConfigManager.KeyWordsLibConfig.PostData + HTTPClient.GetBkn(skey).ToString();
return postData;
}
catch (Exception ex)
{
LogHelp.LogError("Get PostData Error!" + ex);
return null;
}
}

三. HTML解析,POST和GET方法

namespace Test.HtmlParse
{
/// <summary>
/// //网络通信相关
/// </summary>
public class HTTPClient
{

public static CookieContainer cookies = new CookieContainer();
static CookieCollection CookieCollection = new CookieCollection();
static CookieContainer CookieContainer = new CookieContainer();

/// <summary>
/// 获得response内容
/// </summary>
/// <param name="setCookies">out cookie内容</param>
/// <param name="referer"></param>
/// <param name="timeout"></param>
/// <param name="encode"></param>
/// <param name="NoProxy"></param>
/// <returns></returns>
public string Get(out string setCookies,
string url,
string referer = "https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=715030901&daid=73&pt_no_auth=1&s_url=https%3A%2F%2Fqun.qq.com%2F",
int timeout = 100000,
Encoding encode = null,
bool NoProxy = false)
{
if (url == null)
{
setCookies = null;
return null;
}

string dat;
HttpWebResponse res = null;
HttpWebRequest req;
try
{
req = (HttpWebRequest)WebRequest.Create(url);
req.CookieContainer = cookies;
req.AllowAutoRedirect = false;
req.Timeout = timeout;
req.Referer = referer;
if (NoProxy)
req.Proxy = null;
req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36";
res = (HttpWebResponse)req.GetResponse();
setCookies = res.Headers.Get("Set-Cookie");
cookies.Add(res.Cookies);
}
catch (Exception ex)
{
LogHelp.LogError(string.Format("Get {0} response error! ex:{1}", url, ex));
setCookies = null;
return null;
}
StreamReader reader;
reader = new StreamReader(res.GetResponseStream(), encode == null ? Encoding.UTF8 : encode);
dat = reader.ReadToEnd();
res.Close();
req.Abort();
LogHelp.LogDebug(string.Format("Get Method request succeed! - setCookies={0},url ={1}", setCookies, url));
return dat;
}

/// <summary>
/// QR二维码,返回qrsig值
/// </summary>
/// <param name="url"></param>
/// <param name="referer"></param>
/// <param name="timeout"></param>
/// <param name="encode"></param>
/// <param name="NoProxy"></param>
public string GetQRCode(
string url,
string referer = "https://xui.ptlogin2.qq.com/cgi-bin/xlogin?appid=715030901&daid=73&pt_no_auth=1&s_url=https%3A%2F%2Fqun.qq.com%2F",
int timeout = 100000,
Encoding encode = null,
bool NoProxy = false)
{
if (url == null)
return null;

string qrsigCookie = null;
HttpWebResponse res = null;
HttpWebRequest req;
try
{
req = (HttpWebRequest)WebRequest.Create(url);
req.CookieContainer = cookies;
req.AllowAutoRedirect = false;
req.Timeout = timeout;
req.Referer = referer;
if (NoProxy)
req.Proxy = null;
req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36";
res = (HttpWebResponse)req.GetResponse();
cookies.Add(res.Cookies);
}
catch (Exception ex)
{
LogHelp.LogError(string.Format("GetQR {0} response error! ex:{1} ", url, ex));
throw ex;
}
try
{
StreamReader reader;
reader = new StreamReader(res.GetResponseStream(), encode == null ? Encoding.UTF8 : encode);
Bitmap bmap = new Bitmap(res.GetResponseStream());
bmap.Save(@"D:\QRCode.jpg");
//发送邮件
string title = "QQ群登录二维码";
string content = "请在五分钟内扫描登录二维码,过期失效!";
string[] receiveAddrs = KeyWordsLibConfigManager.KeyWordsLibConfig.EmailAddrs.ReceiveAddr.ToArray();
string[] attachAddrs = KeyWordsLibConfigManager.KeyWordsLibConfig.EmailAddrs.AttachUri.ToArray();
EmailPack pack = new EmailPack(title, content, receiveAddrs, null, attachAddrs);
LogHelp.LogInfo(this, "收到邮件发送请求Title:" + title + ",receiveAddrs:" + string.Join(",", receiveAddrs));
pack.Send();

qrsigCookie = res.Headers.Get("set-cookie");
if (qrsigCookie == null)
{
return null;
}
var index1 = qrsigCookie.IndexOf("=");
var index2 = qrsigCookie.IndexOf(";");
qrsigCookie = qrsigCookie.Substring(index1 + 1, 64);
res.Close();
req.Abort();
LogHelp.LogInfo(string.Format("GetQRCode Method request succeed! - qrsigCookie={0},url ={1}", qrsigCookie, url));
return qrsigCookie;
}
catch (Exception ex)
{
LogHelp.LogError("qrsigCookie error or reader wrong! ex:" + ex);
throw ex;
}
}

/// <summary>
/// Post方法
/// </summary>
/// <param name="url">url</param>
/// <param name="postData">post-data </param>
/// <param name="Referer"></param>
/// <param name="timeout"></param>
/// <param name="encode"></param>
/// <returns> reponse content </returns>
internal string Post(
string url,
string postData,
string Referer = "//qun.qq.com/member.html#gid=621859311",
int timeout = 100000,
Encoding encode = null)
{
if (url == null)
return null;
string dat = "";
HttpWebRequest req;
try
{
req = WebRequest.Create(url) as HttpWebRequest;
req.CookieContainer = cookies;
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
req.Proxy = null;
req.Timeout = timeout;
req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36";
req.ProtocolVersion = HttpVersion.Version10;
req.Referer = Referer;

byte[] mybyte = Encoding.Default.GetBytes(postData);
req.ContentLength = mybyte.Length;
Stream stream = req.GetRequestStream();
stream.Write(mybyte, 0, mybyte.Length);
HttpWebResponse res = req.GetResponse() as HttpWebResponse;
cookies.Add(res.Cookies);
stream.Close();
StreamReader SR = new StreamReader(res.GetResponseStream(), encode == null ? Encoding.UTF8 : encode);
dat = SR.ReadToEnd();
res.Close();
req.Abort();
LogHelp.LogDebug(string.Format("Post Method request succeed! - postData={0},url ={1}", postData, url));
}
catch (Exception ex)
{
LogHelp.LogError(string.Format("Post Method error! ex:{0}", ex));
return null;
}
return dat;
}

/// <summary>
/// bkn 解密方法
/// </summary>
/// <param name="skey"></param>
/// <returns></returns>
public static long GetBkn(string skey)
{
var hash = 5381;
for (int i = 0, len = skey.Length; i < len; ++i)
{
hash += (hash << 5) + (int)skey[i];
}
return hash & 2147483647;
}

/// <summary>
/// Get skey string
/// </summary>
/// <param name="setCookie"></param>
/// <returns></returns>
public static string GetSkey(string setCookie)
{
if (setCookie == null)
return null;
string cookieTemp = Regex.Replace(setCookie, @"p_skey", "");
string[] cookies = cookieTemp.Split(';');
string skey = null;
foreach (var c in cookies)
{
if (c.Contains("skey"))
{
int index = c.IndexOf("=");
skey = c.Substring(index + 1);
break;
}
}
return skey;
}

/// <summary>
/// 哈希转换, for qrtoken
/// </summary>
/// <param name="cookie"></param>
/// <returns></returns>
public static int HashConvert(string cookie)
{
int e = 0;
for (int j = 0, k = cookie.Length; k > j; j++)
{
char temp = cookie.ElementAt(j);
e += (e << 5) + Convert.ToByte(temp);
}
return 2147483647 & e;
}

}
}

.net实现扫描二维码登录webqq群抓取qq群信息的更多相关文章

  1. 用c#开发微信 (20) 微信登录网站 - 扫描二维码登录

    像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 1 创建网站应用 在微信开放平台创建一个网站应用 https:// ...

  2. Asp.Net微信登录-电脑版扫描二维码登录

    像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 一.创建网站应用 在微信开放平台创建一个网站应用 https:// ...

  3. C#微信登录-电脑版扫描二维码登录

    像京东,一号店等网站都实现了用微信来登录的功能,就是用手机上的微信扫一扫网站上的二维码,微信上确认后,即可自动用微信的帐号登录网站. 一.创建网站应用 在微信开放平台创建一个网站应用 https:// ...

  4. PC 商城扫描二维码登录

    需求分析: 扫码入口,在pc登录首页新增二维码登录入口 点击扫码入口显示二维码 二维码有效时间为一分钟 超时后显示二维码失效,点击刷新后生成新的二维码 在app端用户登录并扫码后,点击确认登录,进行跳 ...

  5. 实现手机扫描二维码页面登录,类似web微信-第一篇,业务分析

    转自:http://www.cnblogs.com/fengyun99/p/3541249.html 关于XMPP组件的文章,先休息两天,好歹已经完整的写了一份. 这两天,先实现一套关于web微信扫描 ...

  6. Android进阶笔记06:Android 实现扫描二维码实现网页登录

    一. 扫描二维码登录的实现机制: 详细流程图: (1)PC端打开网页(显示出二维码),这时候会保存对应的randnumber(比如:12345678). (2)Android客户端扫码登录,Andro ...

  7. Android扫描二维码 实现 登录网页

    工程代码:ScanQRcode.zip ------------------------------------------------------------------ 1. 扫描二维码登录的实现 ...

  8. 实现手机扫描二维码页面登录,类似web微信-第三篇,手机客户端

    转自:http://www.cnblogs.com/fengyun99/p/3541254.html 上一篇,介绍了二维码生成的机制,紧接着,我们就要开发手机客户端来识别这个二维码. 二维码,实际上是 ...

  9. 实现手机扫描二维码页面登录,类似web微信-第二篇,关于二维码的自动生成

    转自:http://www.cnblogs.com/fengyun99/p/3541251.html 接上一章,我们已经基本把业务逻辑分析清楚了 下面我们第一步,实现二维码的web动态生成. 页面的二 ...

随机推荐

  1. vue文件上传控件

    下载地址:https://pan.baidu.com/s/1Z3pFh2J3xWa8YYnLoseasg 使用方式: <upload ref='upload' action-url='' :mu ...

  2. OpenBUGS抽样数据基本操作

    新建两个文件 第一个文件写操作程序,第二个文件写数据数量,类似于下图 鼠标聚焦在第一个文件中,点击工具栏的Model,选择Specification,然后点击check Moel,会有弹框出现 点击确 ...

  3. 升级node后还是原来版本问题

    解决升级node后,已经安装了最新的版本,但是默认的node版本不是最新版本还是当前版本. 最近遇到个错误:The engine node is incompatible with this modu ...

  4. Java POJO类直接存储在MongoDB中

    记录Java POJO类直接存储在MongoDB中的策略. maven: <dependency> <groupId>org.mongodb</groupId> & ...

  5. ORACLE中RECORD、VARRAY、TABLE的使用详解(转)

    原文地址:ORACLE中RECORD.VARRAY.TABLE的使用详解

  6. mycat环境搭建

    最近工作中突然让搞mycat,特意私下在家先搞一套练个手: 1.先下载一个CentOS7 mini版本就可以(本人机器性能有限): 2.使用VMware创建虚拟机,过程百度下一大堆,这里不做详细介绍. ...

  7. nextcloud大文件无法上传

    I think that if u got a small /tmp like i had u cant upload big file…My /tmp = 462M so i can upload ...

  8. sface

    单步检测方法分为两类:anchor-based如ssd.RetinaNet;2)Anchor-free 如DenseBox.UnitBox;anchor-based处理的尺度范围虽小,更精准:anch ...

  9. vue-calendar 基于 vue 2.0 开发的轻量,高性能日历组件

    vue-calendar-component 基于 vue 2.0 开发的轻量,高性能日历组件 占用内存小,性能好,样式好看,可扩展性强 原生 js 开发,没引入第三方库 Why Github 上很多 ...

  10. setTimeout代替setInterval的写法以及setInterval的弊端以及越来越快的解决办法

    平常经常遇到的一个问题,很多人想间隔时间执行一些事件的时候,第一时间就会想到用setInterval,但是setInterval村子啊不少弊端哦. 弊端1:setInterval会无视错误代码,即使代 ...