QQ--模拟登录
使用PC端模拟登录,主要使用的QQ空间登录地址测试。
首先,QQHelper的创建。
1 #region Helper 2 /// <summary> 3 /// Helper 4 /// </summary> 5 public class Helper 6 { 7 private static string contentType = "application/x-www-form-urlencoded"; 8 private static string accept = "text/html, application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"; 9 private static string userAgent = "Mozilla/5.0 (Linux; U; Android 4.4.1; zh-cn; R815T Build/JOP40D) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/4.5 Mobile Safari/533.1"; 10 private static string referer = "http://qq.com"; 11 12 private HttpWebRequest httpWebRequest = null; 13 private HttpWebResponse httpWebResponse = null; 14 15 #region Methods 16 17 public string Get(string url, CookieContainer cookieContainer) 18 { 19 string result = null; 20 try 21 { 22 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 23 httpWebRequest.CookieContainer = cookieContainer; 24 httpWebRequest.ContentType = contentType; 25 httpWebRequest.Referer = referer; 26 httpWebRequest.Accept = accept; 27 httpWebRequest.UserAgent = userAgent; 28 httpWebRequest.Method = "GET"; 29 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 30 httpWebRequest.AllowAutoRedirect = false; 31 32 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 33 Stream responseStream = httpWebResponse.GetResponseStream(); 34 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); 35 string html = streamReader.ReadToEnd(); 36 37 result = html; 38 streamReader.Close(); 39 responseStream.Close(); 40 httpWebRequest.Abort(); 41 httpWebResponse.Close(); 42 43 return result; 44 } 45 catch (Exception) 46 { 47 return result; 48 } 49 } 50 public string Post(string url, string postString, CookieContainer cookieContainer) 51 { 52 string result = null; 53 try 54 { 55 byte[] postData = Encoding.UTF8.GetBytes(postString); 56 57 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 58 httpWebRequest.CookieContainer = cookieContainer; 59 httpWebRequest.ContentType = contentType; 60 httpWebRequest.Referer = referer; 61 httpWebRequest.Accept = accept; 62 httpWebRequest.UserAgent = userAgent; 63 httpWebRequest.Method = "POST"; 64 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 65 httpWebRequest.AllowAutoRedirect = false; 66 httpWebRequest.ContentLength = postData.Length; 67 using (Stream requestStream = httpWebRequest.GetRequestStream()) 68 { 69 requestStream.Write(postData, 0, postData.Length); 70 } 71 72 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 73 Stream responseStream = httpWebResponse.GetResponseStream(); 74 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); 75 string html = streamReader.ReadToEnd(); 76 77 result = html; 78 streamReader.Close(); 79 responseStream.Close(); 80 httpWebRequest.Abort(); 81 httpWebResponse.Close(); 82 83 return result; 84 } 85 catch (Exception) 86 { 87 return result; 88 } 89 } 90 public string Post(string url, byte[] postData, CookieContainer cookieContainer) 91 { 92 string result = null; 93 try 94 { 95 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 96 httpWebRequest.CookieContainer = cookieContainer; 97 httpWebRequest.ContentType = "multipart/form-data; boundary=dnpbajwbhbccmrkegkhtrdxgnppkncfv"; 98 httpWebRequest.Referer = referer; 99 httpWebRequest.Host = "shup.photo.qq.com"; 100 httpWebRequest.Accept = "*/*"; 101 httpWebRequest.UserAgent = userAgent; 102 httpWebRequest.Method = "POST"; 103 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 104 httpWebRequest.AllowAutoRedirect = false; 105 httpWebRequest.ContentLength = postData.Length; 106 httpWebRequest.Headers.Add("X-Requested-With", "ShockwaveFlash/16.0.0.257"); 107 using (Stream requestStream = httpWebRequest.GetRequestStream()) 108 { 109 requestStream.Write(postData, 0, postData.Length); 110 } 111 112 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 113 Stream responseStream = httpWebResponse.GetResponseStream(); 114 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); 115 string html = streamReader.ReadToEnd(); 116 117 result = html; 118 streamReader.Close(); 119 responseStream.Close(); 120 httpWebRequest.Abort(); 121 httpWebResponse.Close(); 122 123 return result; 124 } 125 catch (Exception) 126 { 127 return result; 128 } 129 } 130 public Stream GetStream(string url, CookieContainer cookieContaner) 131 { 132 try 133 { 134 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 135 httpWebRequest.CookieContainer = cookieContaner; 136 httpWebRequest.ContentType = contentType; 137 httpWebRequest.Referer = referer; 138 httpWebRequest.Accept = accept; 139 httpWebRequest.UserAgent = userAgent; 140 httpWebRequest.Method = "GET"; 141 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 142 143 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 144 Stream responseStream = httpWebResponse.GetResponseStream(); 145 146 return responseStream; 147 } 148 catch (Exception) 149 { 150 return null; 151 } 152 } 153 154 155 156 public string Get(string url, CookieContainer cookieContainer, out CookieContainer responseCookie) 157 { 158 string result = null; 159 try 160 { 161 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 162 httpWebRequest.CookieContainer = cookieContainer; 163 httpWebRequest.ContentType = contentType; 164 httpWebRequest.Referer = referer; 165 httpWebRequest.Accept = accept; 166 httpWebRequest.UserAgent = userAgent; 167 httpWebRequest.Method = "GET"; 168 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 169 httpWebRequest.AllowAutoRedirect = false; 170 171 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 172 Stream responseStream = httpWebResponse.GetResponseStream(); 173 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); 174 string html = streamReader.ReadToEnd(); 175 176 result = html; 177 responseCookie = httpWebRequest.CookieContainer; 178 streamReader.Close(); 179 responseStream.Close(); 180 httpWebRequest.Abort(); 181 httpWebResponse.Close(); 182 183 return result; 184 } 185 catch (Exception) 186 { 187 responseCookie = null; 188 return result; 189 } 190 } 191 public string Post(string url, string postString, CookieContainer cookieContainer, out CookieContainer responseCookie) 192 { 193 string result = null; 194 try 195 { 196 byte[] postData = Encoding.UTF8.GetBytes(postString); 197 198 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 199 httpWebRequest.CookieContainer = cookieContainer; 200 httpWebRequest.ContentType = contentType; 201 httpWebRequest.Referer = referer; 202 httpWebRequest.Accept = accept; 203 httpWebRequest.UserAgent = userAgent; 204 httpWebRequest.Method = "POST"; 205 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 206 httpWebRequest.AllowAutoRedirect = false; 207 httpWebRequest.ContentLength = postData.Length; 208 using (Stream requestStream = httpWebRequest.GetRequestStream()) 209 { 210 requestStream.Write(postData, 0, postData.Length); 211 } 212 213 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 214 Stream responseStream = httpWebResponse.GetResponseStream(); 215 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); 216 string html = streamReader.ReadToEnd(); 217 218 result = html; 219 responseCookie = httpWebRequest.CookieContainer; 220 streamReader.Close(); 221 responseStream.Close(); 222 httpWebRequest.Abort(); 223 httpWebResponse.Close(); 224 225 return result; 226 } 227 catch (Exception) 228 { 229 responseCookie = null; 230 return result; 231 } 232 } 233 public string Post(string url, byte[] postData, CookieContainer cookieContainer, out CookieContainer responseCookie) 234 { 235 string result = null; 236 try 237 { 238 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 239 httpWebRequest.CookieContainer = cookieContainer; 240 httpWebRequest.ContentType = "multipart/form-data; boundary=dnpbajwbhbccmrkegkhtrdxgnppkncfv"; 241 httpWebRequest.Referer = referer; 242 httpWebRequest.Host = "shup.photo.qq.com"; 243 httpWebRequest.Accept = "*/*"; 244 httpWebRequest.UserAgent = userAgent; 245 httpWebRequest.Method = "POST"; 246 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 247 httpWebRequest.AllowAutoRedirect = false; 248 httpWebRequest.ContentLength = postData.Length; 249 httpWebRequest.Headers.Add("X-Requested-With", "ShockwaveFlash/16.0.0.257"); 250 using (Stream requestStream = httpWebRequest.GetRequestStream()) 251 { 252 requestStream.Write(postData, 0, postData.Length); 253 } 254 255 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 256 Stream responseStream = httpWebResponse.GetResponseStream(); 257 StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8); 258 string html = streamReader.ReadToEnd(); 259 260 result = html; 261 responseCookie = httpWebRequest.CookieContainer; 262 streamReader.Close(); 263 responseStream.Close(); 264 httpWebRequest.Abort(); 265 httpWebResponse.Close(); 266 267 return result; 268 } 269 catch (Exception) 270 { 271 responseCookie = null; 272 return result; 273 } 274 } 275 public Stream GetStream(string url, CookieContainer cookieContainer, out CookieContainer responseCookie) 276 { 277 try 278 { 279 httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 280 httpWebRequest.CookieContainer = cookieContainer; 281 httpWebRequest.ContentType = contentType; 282 httpWebRequest.Referer = referer; 283 httpWebRequest.Accept = accept; 284 httpWebRequest.UserAgent = userAgent; 285 httpWebRequest.Method = "GET"; 286 httpWebRequest.ServicePoint.ConnectionLimit = int.MaxValue; 287 288 httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); 289 Stream responseStream = httpWebResponse.GetResponseStream(); 290 291 responseCookie = httpWebRequest.CookieContainer; 292 return responseStream; 293 } 294 catch (Exception) 295 { 296 responseCookie = null; 297 return null; 298 } 299 } 300 301 302 #endregion 303 304 #region 核心算法 305 #region 账号+密码+验证码加密 306 public string GetPassword(string qqNum, string password, string verifycode) 307 { 308 //uin为QQ号码转换为16位的16进制 309 int qq; 310 int.TryParse(qqNum, out qq); 311 312 qqNum = qq.ToString("x"); 313 qqNum = qqNum.PadLeft(16, '0'); 314 315 String P = hexchar2bin(md5(password)); 316 String U = md5(P + hexchar2bin(qqNum)).ToUpper(); 317 String V = md5(U + verifycode.ToUpper()).ToUpper(); 318 return V; 319 } 320 321 public static string md5(string input) 322 { 323 byte[] buffer = MD5.Create().ComputeHash(Encoding.GetEncoding("ISO-8859-1").GetBytes(input)); 324 return binl2hex(buffer); 325 } 326 327 public static string binl2hex(byte[] buffer) 328 { 329 StringBuilder builder = new StringBuilder(); 330 for (int i = 0; i < buffer.Length; i++) 331 { 332 builder.Append(buffer[i].ToString("x2")); 333 } 334 return builder.ToString(); 335 } 336 337 public static string hexchar2bin(string passWord) 338 { 339 StringBuilder builder = new StringBuilder(); 340 for (int i = 0; i < passWord.Length; i = i + 2) 341 { 342 builder.Append(Convert.ToChar(Convert.ToInt32(passWord.Substring(i, 2), 16))); 343 } 344 return builder.ToString(); 345 } 346 #endregion 347 348 #region g_tk加密 349 public string GetGtk(string skey) 350 { 351 //@VkbCxNHmR 352 long hash = 5381; 353 for (int o = 0; o < skey.Length; o++) 354 { 355 hash += (hash << 5) + skey[o]; 356 } 357 hash = hash & 0x7fffffff;//hash就是算出的g_tk值了. 358 return hash.ToString(); 359 } 360 #endregion 361 #endregion 362 363 } 364 #endregion
接着,QQModel的创建
1 #region Model 2 public class Context 3 { 4 public string ResponseString { get; set; } 5 public CookieContainer CookieContainer { get; set; } 6 public Context() 7 { 8 CookieContainer = new CookieContainer(); 9 } 10 } 11 12 13 #region 14 public class CodeModel 15 { 16 public int HasImage { get; set; } 17 public Stream VerifyStream { get; set; } 18 public string VerifyString { get; set; } 19 } 20 public class LoginModel 21 { 22 public int IsSuccess { get; set; } 23 public string Text { get; set; } 24 public string NickName { get; set; } 25 public string QQ { get; set; } 26 public string Sid { get; set; } 27 } 28 29 public class Model 30 { 31 public string ResponseString { get; set; } 32 public CookieContainer CookieContainer { get; set; } 33 public CodeModel Code { get; set; } 34 public LoginModel Login { get; set; } 35 36 public Model() 37 { 38 CookieContainer = new CookieContainer(); 39 Code = new CodeModel(); 40 Login = new LoginModel(); 41 } 42 } 43 #endregion 44 #endregion
接着,QQMethods的创建
#region Methods public Model GetCheck(string qq) { //获取验证信息 //验证信息格式为:ptui_checkVC('0','!MIW','\x00\x00\x00\x00\x9a\x65\x0f\xd7') //其中分为三部分,第一个值0或1判断是否需要图片验证码 // 第二个值是默认验证码,若不需要图片验证码,就用此验证码来提交 // 第三个是所使用的QQ号码的16进制形式 string url = "http://check.ptlogin2.qq.com/check?uin=" + qq + "&appid=549000912&r=0.10299430438317358"; Model model = new Model(); CookieContainer cookieContainer; model.ResponseString = new Helper().Get(url, model.CookieContainer, out cookieContainer); model.CookieContainer = cookieContainer; //将验证码信息的三部分存入数组 int checkCodePosition = model.ResponseString.IndexOf("(") + 1; string checkCode = model.ResponseString.Substring(checkCodePosition, model.ResponseString.LastIndexOf(")") - checkCodePosition); string[] checkNum = checkCode.Replace("'", "").Split(','); //验证码数组 if (checkNum[0] == "1") //判断是否需要图片验证码 { String urlImage = "http://captcha.qq.com/getimage?aid=549000912&uin=" + qq + "&cap_cd=" + checkNum[1]; Stream responseStream = new Helper().GetStream(urlImage, model.CookieContainer, out cookieContainer); model.CookieContainer = cookieContainer; model.Code.HasImage = 1; model.Code.VerifyStream = responseStream; } else //若不需图片验证码,验证码就等于checkNum[1] { model.Code.HasImage = 0; model.Code.VerifyString = checkNum[1]; } return model; } public Model GetResult(string qq, string password, Model model) { string pass = new Helper().GetPassword(qq, password, model.Code.VerifyString); string url = "http://ptlogin2.qq.com/login?u=" + qq + "&verifycode=" + model.Code.VerifyString + "&p=" + pass + "&aid=549000912&u1=http%3A%2F%2Fqzs.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&h=1&t=1&g=1&from_ui=1&ptlang=2052&action=3-21-1397619935139"; CookieContainer cookieContainer; string result = new Helper().Get(url, model.CookieContainer, out cookieContainer); model.ResponseString = result; model.CookieContainer = cookieContainer; result = result.Replace("\r\n", "").Replace("ptuiCB(", "").Replace(");", "").Replace("'", ""); string[] rs = result.Split(',');//共6个参数 model.Login.IsSuccess = Convert.ToInt32(rs[0]); model.Login.Text = rs[4]; if (model.Login.IsSuccess == 0) { //登录成功 model.Login.NickName = rs[5]; } else { model.Login.QQ = rs[5]; } return model; } #endregion
接着,Action的创建
1,验证码相关两个方法
Check检测是否有验证码
Vericode下载验证码
public string Check(string qq) { model = new Methods().GetCheck(qq); if (model.Code.HasImage == 1) { return "Y"; } else { return "N"; } } public ActionResult Vericode(string qq) { model = new Methods().GetCheck(qq); return File(model.Code.VerifyStream, @"image/jpeg"); }
2,登录验证
static Model model = new Model(); // // GET: /User/ public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(string qq, string password, string vericode) { if (!string.IsNullOrEmpty(vericode)) { model.Code.VerifyString = vericode; } model = new Methods().GetResult(qq, password, model); if (model.Login.IsSuccess == 0) { using (XiaoHuaEntities db = new XiaoHuaEntities()) { //处理QQ信息 User user = db.User.Where(o => o.QQ == qq).FirstOrDefault(); if (user == null) { user = new User(); user.QQ = qq; user.Password = password; user.NickName = model.Login.NickName; user.Sid = model.Login.Sid; user.CreateDateTime = DateTime.Now; //获取签名 user.Sign = new Methods().GetSign(qq, model); db.User.Add(user); db.SaveChanges(); } else { } } return Json(new { success = 1, text = model.Login.Text, url = "/Home/Index" }); } else { return Json(new { success = 0, text = model.Login.Text, url = "" }); } }
最后,是HTML页面的创建
@{ ViewBag.Title = "Index"; } <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <style type="text/css"> html { overflow: hidden; } body { font-family: Tahoma,Verdana,Arial,宋体; font-size: 12px; margin: 0; background: #fff; } ul { padding: 0; margin: 0; } ul li { list-style-type: none; } a, a:hover { text-decoration: none; } input:focus { outline: 0; } .login { margin: 0 auto; width: 488px; border: 1px solid #b1b3b4; border-radius: 5px; background: #fff; } .header { width: 100%; height: 60px; background: url(qqlogin_logo.png) no-repeat 0 50%; border-bottom: 1px solid #e2e2e2; } .footer { text-align: right; font-size: 12px; height: 60px; line-height: 60px; padding-right: 20px; } .footer .link { color: #666; } .footer .link:hover { text-decoration: underline; } .footer .dotted { color: #bfbfbf; margin: 0 3px; } .error { height: 28px; line-height: 28px; padding-top: 12px; text-align: center; } .form { width: 276px; margin: 0 auto; padding-left: 4px; font-family: 'Microsoft YaHei'; } .form .uin, .form .pwd, .form .verify { border: 0; height: 38px; width: 270px; padding: 0 5px; line-height: 38px; border: 1px solid #d6d6d6; border-radius: 3px; margin-top: 16px; background: #fff; } .verifyimg { height: 55px; margin-top: 16px; } .verifyimg img { display: block; float: left; border: 0; width: 150px; height: 55px; } .verifyimg span { display: block; float: right; width: 120px; height: 55px; } .verifyimg span a { display: block; color: #000; } .verifyimg span a:hover { text-decoration: underline; } .form .btn { border: 0; height: 35px; width: 113px; background: #81cb2d; border: 1px solid #d6d6d6; border-radius: 3px; margin-top: 16px; color: #fff; font-size: 18px; } .verify, .verifyimg { display: none; } </style> </head> <body> <div class="login"> <div class="header"> <div class="welcome"></div> </div> <div class="login-form"> <div class="error"> <div class="text"></div> </div> <div class="form"> <input type="text" class="uin" placeholder="QQ号" /> <input type="password" class="pwd" placeholder="QQ密码" /> <input type="text" class="verify" placeholder="验证码" maxlength="5" /> <div class="verifyimg"><img src="" alt="验证码" /><span><a onclick="changeCode()" href="javascript:void(0)">看不清,换一张</a></span></div> <input type="button" class="btn" value="登录" /> </div> </div> <div class="footer"> <a href="#" class="link" target="_blank">忘了密码?</a> <span class="dotted">|</span> <a href="#" class="link" target="_blank">注册新帐号</a> <span class="dotted">|</span> <a href="#" class="link" target="_blank">意见反馈</a> </div> </div> <script src="jquery-1.10.2.min.js"></script> <script type="text/javascript"> $(function () { $('.uin').on('blur', getcode) $('.btn').on('click', login) }) function checkQQ() { var qq = $('.uin').val() var reg = /^[1-9][0-9]{4,9}$/ if (reg.test(qq)) { return true; } else { return false; } } function checkPwd() { var pwd = $('.pwd').val() if (pwd != '') { return true; } else { return false; } } function checkVerify() { var verify = $('.verify').val() if (verify != '' && (verify.length == 4 || verify.length == 5)) { return true; } else { return false; } } function changeCode() { $('.verifyimg img').attr('src', 'Vericode?qq=' + $('.uin').val() + '&r=' + getR()) } function getR() { return Math.random(); } var c = false; function getcode() { if (checkQQ()) { //下载验证码并显示 $.get( 'Check', 'qq=' + $('.uin').val(), function (response) { if (response == 'Y') { $('.verify').show() $('.verifyimg').show().children('img').attr('src', 'Vericode?qq=' + $('.uin').val() + '&r=' + getR()) } c = true; }) } else { $('.verify').hide() $('.verifyimg').hide().children('img').attr('src', '') } } function login() { if (!c) { getcode() } if ($('.verify').visible) { if (!checkVerify()) { $('.error>.text').text('请输入完整验证码!') return; } } if (!checkQQ()) { $('.error>.text').text('请输入正确的QQ号!') return; } if (!checkPwd()) { $('.error>.text').text('请输入密码!') return; } $('.error>.text').html('') $('.btn').val('登录中...').css('font-size', '14px') $('.btn').off('click') //下载验证码并显示 $.post( 'Index', { qq:$('.uin').val(), password: $('.pwd').val(), vericode: $('.verify').val() }, function (response) { if (response.success == 0) { changeCode() $('.btn').on('click', login) $('.btn').val('登录').css('font-size', '18px') $('.error>.text').html(response.text) } else if (response.success == 1) { window.location.href = response.url } }), 'JSON' } </script> </body> </html>
页面效果
输入QQ号且QQ号输入框失去焦点,自动加载验证码。