上次說到怎么獲取BAIDUID,這個相信很多人都能夠拿到就不多說了,今天一連說兩個,獲取token和raskey
2、利用以上獲得的cookie直接訪問頁面
在第一篇文章中寫到這個,拿着我們儲存到的BAIDUID直接請求這個頁面,就能夠獲取到反饋回來的Json格式的數據
這里的話需要用到一個dll,添加引用到項目【
Newtonsoft.Json】
至於這個文檔怎么用,已經有其他前輩的博文中說到,我這里就不解釋了,如果不懂的可以在后面看代碼
如果你拿不到token,那么只有一個問題,你沒有BAIDUID,如果你確認第一次是收集到了,那么請重復檢驗在請求token時這個Cookies是否還存在。(
很多時候是Cookies的效期問題導致Cookies收集器將失效的BAIDUID自動丟棄)
有了前面的步驟,拿到raskey也就很簡單了,步驟是一樣的,將前面所有的Cookies都保存下來,接下來
3、用token訪問該地址,獲取raskey
https://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;
}今天就到這里,明天說說驗證碼的問題,不過很大部分情況下,除非你的密碼幾次輸入錯誤或者異地登錄,不然一般不會讓你輸入驗證碼,如有問題歡迎評論交流
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;
}今天就到這里,明天說說驗證碼的問題,不過很大部分情況下,除非你的密碼幾次輸入錯誤或者異地登錄,不然一般不會讓你輸入驗證碼,如有問題歡迎評論交流