C#模拟百度登录并到指定网站评论回帖(三)

  上次说到怎么获取BAIDUID,这个相信很多人都能够拿到就不多说了,今天一连说两个,获取token和raskey

  2、利用以上获得的cookie直接访问页面

https://passport.baidu.com/v2/api/?getapi&tpl=zongheng&apiver=v3&tt=1441287460704&class=login&gid=26D2A76-9D6C-4EBE-8687-25C6591194B2&logintype=basicLogin&callback=bd__cbs__v9tdyy获取参数token

在第一篇文章中写到这个,拿着我们储存到的BAIDUID直接请求这个页面,就能够获取到反馈回来的Json格式的数据

这里的话需要用到一个dll,添加引用到项目【Newtonsoft.Json】

至于这个文档怎么用,已经有其他前辈的博文中说到,我这里就不解释了,如果不懂的可以在后面看代码

如果你拿不到token,那么只有一个问题,你没有BAIDUID,如果你确认第一次是收集到了,那么请重复检验在请求token时这个Cookies是否还存在。(很多时候是Cookies的效期问题导致Cookies收集器将失效的BAIDUID自动丢弃)

  有了前面的步骤,拿到raskey也就很简单了,步骤是一样的,将前面所有的Cookies都保存下来,接下来

  3、用token访问该地址,获取raskeyhttps://passport.baidu.com/v2/getpublickey?token=5d0fc87cb0de39982c06795d3356e239&tpl=zongheng&apiver=v3&tt=1441311621601&gid=59723A6-1178-4614-B7AF-779917BC4453&callback=bd__cbs__gaci47和publickey,注意将地址中的值替换。

  

  很明显,你会发现反馈回来的也是一个Json数据,但可以看到后面有一串以-----BEGIN PUBLIC KEY----- 开头以----End Public KEY----结尾的数据,那里面就是publickey,而紧跟在后的key后的字符串就是raskey,用上面同样的办法拿到这两组数据,切记前一组要将开头和结尾的标识字符串也要截取出来,而不是单纯的乱字符串。

  现在算一下我们拿到的东西:3个页面的Cookies、token、publickey、raskey

这几个都齐全了,那么就可以向百度提交post请求登录,但在这之前,你需要准备一串经过ras加密过后的密码,否则会一直提示密码错误,也就是err_7。

这块需要添加另外一个引用【BouncyCastle.Crypto.dll】这是哪个大神写的就不清楚了,但非常实用,很感谢这些大神做出的贡献。之后添加一个类:

Newtonsoft.Json.Net35.dll(Josn数据解析)

BouncyCastle.Crypto.dll

using System;

using System.IO;

using System.Security.Cryptography;

using System.Text;

using Org.BouncyCastle.Crypto;

using Org.BouncyCastle.Crypto.Parameters;

using Org.BouncyCastle.OpenSsl;

using Org.BouncyCastle.Security;

namespace 纵横小说自动评论

{

/// <summary>

/// rsakey密码加密帮助

/// </summary>

public class RsaHelper

{

public static string PemToXml(string pem)

{

if (pem.StartsWith("-----BEGIN RSA PRIVATE KEY-----")

|| pem.StartsWith("-----BEGIN PRIVATE KEY-----"))

{

return GetXmlRsaKey(pem, obj =>

{

if ((obj as RsaPrivateCrtKeyParameters) != null)

return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)obj);

var keyPair = (AsymmetricCipherKeyPair)obj;

return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keyPair.Private);

}, rsa => rsa.ToXmlString(true));

}

if (pem.StartsWith("-----BEGIN PUBLIC KEY-----"))

{

return GetXmlRsaKey(pem, obj =>

{

var publicKey = (RsaKeyParameters)obj;

return DotNetUtilities.ToRSA(publicKey);

}, rsa => rsa.ToXmlString(false));

}

throw new InvalidKeyException("Unsupported PEM format...");

}

private static string GetXmlRsaKey(string pem, Func<object, RSA> getRsa, Func<RSA, string> getKey)

{

using (var ms = new MemoryStream())

using (var sw = new StreamWriter(ms))

using (var sr = new StreamReader(ms))

{

sw.Write(pem);

sw.Flush();

ms.Position = 0;

var pr = new PemReader(sr);

object keyPair = pr.ReadObject();

using (RSA rsa = getRsa(keyPair))

{

var xml = getKey(rsa);

return xml;

}

}

}

/// <summary>

/// RSA加密

/// </summary>

/// <param name="publickey"></param>

/// <param name="content"></param>

/// <returns></returns>

public static string RSAEncrypt(string publickey, string content)

{

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

byte[] cipherbytes;

rsa.FromXmlString(publickey);

cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false);

return Convert.ToBase64String(cipherbytes);

}

/// <summary>

/// RSA解密

/// </summary>

/// <param name="privatekey"></param>

/// <param name="content"></param>

/// <returns></returns>

public static string RSADecrypt(string privatekey, string content)

{

privatekey =

@"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>";

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

byte[] cipherbytes;

rsa.FromXmlString(privatekey);

cipherbytes = rsa.Decrypt(Convert.FromBase64String(content), false);

return Encoding.UTF8.GetString(cipherbytes);

}

}

}好了,用这个类将密码加密后就Post所有数据吧,下面是具体实现代码

//获取token
        private Regex _regex = new Regex(@"\{.*\}", RegexOptions.IgnoreCase);
        /// <summary>
        /// 根据BAIDUID获取token
        /// </summary>
        public string GetToken()
        {
            HttpCookie cookie = new HttpCookie("BDRCVFR[gltLrB7qNCt]");
            cookie.Value = "mk3SLVN4HKm";
            cookie.Expires = DateTime.Now.AddDays(1);
           string url_getToken = string.Format("https://passport.baidu.com/v2/api/?getapi&tpl=zongheng&apiver=v3&tt={0}&class=login&gid=0743012-DD22-4632-B84E-B054B933DDA0&logintype=basicLogin&callback=bd__cbs__xjugf7", Utility.GetTimeStamp());
           string token_get = helper.GetPageResponse_Get(url_getToken, Utility.UrlDecode("http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F"), "*/*");
           if (_regex.IsMatch(token_get))
               token_get = _regex.Match(token_get).Value;
           var resultToken = JsonConvert.DeserializeObject<ResultToken>(token_get);
            if (string.IsNullOrEmpty(resultToken.Data.Token))
            {
                ShowLog("Parameter-:获取token=" + resultToken.Data.Token + "失败\n");
                return null;
            }
            return resultToken.Data.Token;
        }
        //获取raskey
        public string GetRasKey(string token)
        {
            string url_RasKey = string.Format("https://passport.baidu.com/v2/getpublickey?token={0}&tpl=zongheng&apiver=v3&tt={1}&gid=399423B-A0F5-42A0-B07F-CC5290F8F95D&callback=bd__cbs__xjugf7", token, Utility.GetTimeStamp());
            string publicKey = helper.GetPageResponse_Get(url_RasKey, Utility.UrlDecode("http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F"), "*/*");
            //获取raskey
            if (_regex.IsMatch(publicKey))
                publicKey = _regex.Match(publicKey).Value;
            var result_publicKey = JsonConvert.DeserializeObject<PublicRsaKey>(publicKey);
            var rsakey = result_publicKey.Key;
            //将密码加密
            var pemToXml = RsaHelper.PemToXml(result_publicKey.Pubkey);
            pwd = RsaHelper.RSAEncrypt(pemToXml, pwd);
            //日志
            if (!string.IsNullOrEmpty(rsakey))
                return rsakey;
                ShowLog("Parameter-:获取publickey=" + result_publicKey.Pubkey + "失败!");
                ShowLog("Parameter-:获取raskey=" + rsakey + "失败!");
                return null;
        }/// <summary>
        /// 登录实现
        /// </summary>
        public LoginStatus Login(string verifycode, string codestring, string token, string raskey, int userIndex)
        { 
            string loginresult = "";
            string url_Post = "https://passport.baidu.com/v2/api/?login";
           long tt= Utility.GetTimeStamp();
            string postData = string.Format("verifycode={0}&username={1}&u=http://zongheng.baidu.com/sendbduss.do?source=0&location=http%3A%2F%2Fwww.zongheng.com%2F&_t={2}&tt={3}&tpl=zongheng&token={4}&staticpage=http://passport.zongheng.com/v3Jump.html&safeflg=0&rsakey={5}&quick_user=0&ppui_logintime=20266&password={6}&mem_pass=on&logLoginType=pc_loginBasic&logintype=basicLogin&loginmerge=true&isPhone=false&gid=0743012-DD22-4632-B84E-B054B933DDA0&detect=1&crypttype=12&codestring={7}&charset=utf-8&callback=parent.bd__pcbs__ok0875&apiver=v3", verifycode, HttpUtility.UrlEncode(userName), tt,tt, HttpUtility.UrlEncode(token), HttpUtility.UrlEncode(raskey), HttpUtility.UrlEncode(pwd), codestring);
            loginresult =helper.GetPageResponse_Post(url_Post, postData, Utility.UrlDecode("http://passport.zongheng.com/?location=http%3A%2F%2Fwww.zongheng.com%2F"));
            //分析loginresult
            string err = @"(?<=err_no=)[^&]+?(?=&)";
            Match regx = Regex.Match(loginresult, err);
            string codestr = "(?<=codeString=)[^&]+?(?=&)";
            string codetype = "(?<=vcodetype=)[^&]+?(?=&)";
            Match regx2 = Regex.Match(loginresult, codestr);
            Match regx3 = Regex.Match(loginresult, codetype);
            string errno = regx.Value;
            _codestring = regx2.Value;
            vcodeType= regx3.Value;
            //根据返回的错误号提示信息,并且请求验证码
               switch (errno)
               {
                   case "257": 
                       return LoginStatus.codeGet;
                   case "7": ShowLog("账号或密码错误...");
                       ChangeStauts("失败", userIndex);
                       return LoginStatus.loginFail;;
                   case "0": ShowLog("登录成功...");
                       ChangeStauts("成功", userIndex);
                       break;
                   default: ShowLog("未知错误...");
                       ChangeStauts("错误", userIndex);
                       return LoginStatus.Error;;
               }
               return LoginStatus.loginSucceed;
        }今天就到这里,明天说说验证码的问题,不过很大部分情况下,除非你的密码几次输入错误或者异地登录,不然一般不会让你输入验证码,如有问题欢迎评论交流

时间: 2024-08-24 22:52:51

C#模拟百度登录并到指定网站评论回帖(三)的相关文章

C#模拟百度登录并到指定网站评论回帖(五)

前面的四篇已经说完了全部的模拟百度登录,接下来就是到指定的网站去发表评论,当然你也可能是获取其他信息,其实这些套路都是万变不离其宗的,弄懂之后觉得像这种请求-响应获取信息的功能实在很简单(想起当初走的弯路,真是太心酸了) 今天的详细评论过程就不多说了,这里就指出一下我在写这个功能的时候遭遇的问题,也正是这些问题导致陷入了困境.(主要是理论,有不懂的童鞋欢迎评论交流) 第一个问题:如果使用的百度登录网站,那么前面我们获取到BDUSS之后,到这里就要发生转换.因为我访问的网页,在访问主页的时候会通过

C#模拟百度登录并到指定网站评论回帖(一)

核心信息: 请求网址:  https://passport.baidu.com/v2/api/?login请求方法:  POST状态码:  HTTP/1.1 200 OK请求头 //用户代理 UserAgent,是指浏览器,它的信息包括硬件平台.系统软件.应用软件和用户个人偏好.在X.400电子系统中,用户代理是一种对数据打包.创造分组头,以及编址.传递消息的部件.用户代理并不是仅指浏览器,还包括搜索引擎. User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW

C#模拟百度登录并到指定网站评论回帖(四)

基本的实现功能前面已经全部讲完,基本上可以复制黏贴完成登录百度的过程了 今天的这一贴就说说怎么获取百度的验证码 内容回顾:还记得前面第一贴说的如果登录发生异常,百度会发回2个值吗?是的,就是codeType和codeString这两个值,用前面的JSON数据解析可以分别获取. 前面也说到codeType是不变的(至少同一次请求时不变).请求验证码的时候会要求传递这个参数,所以要想得到正确的验证码,这个参数是必不可少的,否则你请求多少次都是一个错误的验证码! 具体代码入下: //封装更换验证码  

模拟百度登录并到指定网站评论回帖

http://www.zfs.cn/home.php?mod=space&uid=674782&do=profile&from=spacehttp://www.zfs.cn/home.php?mod=space&uid=674783&do=profile&from=spacehttp://www.zfs.cn/home.php?mod=space&uid=674784&do=profile&from=spacehttp://www.z

C#模拟百度登录

目录: 1.fiddler解析百度登录地址 2.处理传入参数 1.fiddler解析百度登录地址 因工作需要,所以研究了下百度的登陆.首先打开https://passport.baidu.com/v2/?login,我们用fiddler很快就能找到百度的登录入口https://passport.baidu.com/v2/api/?login .如下图: 在登录入口https://passport.baidu.com/v2/api/?login 之前,百度先会去获取publickey和token.

模拟百度空间登录

我的个人博客( 肥龙的博客)发表了新文章了! 欢迎大家过来阅读,以下是文章的连接地址 http://www.comingcode.com/?p=357 由于自己有了个人的博客,但是又想提高点曝光率,所以就想到如何将自己的博客在其他网站曝光多点,当然最恶心的就是到每个网站或论坛上面发广告,这样不但可以增加曝光度,同样也能拉点仇恨.不管出于什么目的,如果是想在各个网站上手动一条条发的话,估计这个人也够忙的了. 学习了python后,就可以实现自动将博客同步到别的网站上了,要做的只是模拟用户登录,然后

C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站

原文:C# 利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站 我们经常会碰到需要程序模拟登录一个网站,那如果网站需要填写验证码的要怎样模拟登录呢?这篇文章利用了 HttpWebRequest 和 HttpWebResponse 模拟登录了有验证码的网站. 程序设计的界面很简单,三个TextBox分别输入用户名.密码和验证码,一个Image控件显示从网站请求到的验证码图片,还有两个按钮,一个换验证码,一个登录. 写程序前,先用浏览器的开发者工具观察下登

利用 HttpWebRequest 和 HttpWebResponse 模拟登录有验证码的网站

需要用程序模拟登录一个网站,登录的时候需要填写验证码. 设计的界面很简单: 写程序前,先用浏览器的开发者工具观察下登录页面有什么请求,我这里用的是 FireBug,下面两个图是在 FireBug 的网络面板中截的. 可以看到打开登录页面时有个 GET 请求验证码的,在 FireBug 中可以看到: 上面的图上可以看到这一句: Set-Cookie GUID=c89eabb62d9d4f35b491a8afd371b4ad; path=/ 这里请求的验证码页面保存了一个Cookie. 然后我们输入

python模拟自动登录网站(urllib2)

不登录打开网页: import urllib2 request = urllib2.Request('http://www.baidu.com') response = urllib2.urlopen(request).read() print response 保存网页图片(https://www.baidu.com/img/bd_logo1.png): picurl = 'https://www.baidu.com/img/bd_logo1.png' #定义图片的url地址 req = ur