百度登录协议分析
登录百度前需要先获取必要的Cookies 和一些参数 Token, CodeString
首先,要获取的是 BAIDUID Cookie,如果没有这个 Cookie,那么Token和CodeString就不能够获取。获取 BAIDUID Cookie 很简单,打开百度首页,百度服务器就会返回 BAIDUID Cookie。
其次,获取 Token 和 CodeStrin,Token 是登录百度时Post 中的一个参数,CodeString 是获取验码时会用到。通过访问url
https://passport.baidu.com/v2/api/?getapi&tpl=ik&apiver=v3&tt=1371883487&class=login
URL 地址其中几个参数的意义:
tpl 不知道是做什么用,一是固定的写 ik 就可以了
apiver 的值是固定的 API的版本号
tt 是时间戳
class 动作类别,登录时是login,注册百度帐号时是reg
服务器会返回 Json 结构的数据,其中包含了 Token 和 CodeString:
{
"errInfo": {
"no": "0"
},
"data": {
"rememberedUserName": "",
"codeString": "",
"token": "d45f26cf74aa65c3088f699b8791f9eb",
"cookie": "1"
}
}
"errInfo": {
"no": "0"
},
"data": {
"rememberedUserName": "",
"codeString": "",
"token": "d45f26cf74aa65c3088f699b8791f9eb",
"cookie": "1"
}
}
codeString 一般为空,如果不为空,那么登录时就需要验证码。所以可以根据这个值进行判断登录时是需要验证码。获取验证码的URL:
https://passport.baidu.com/cgi-bin/genimage? //?后跟CodeString的值
解析 Json 有很多方法,如果使用 C# 可以使用 Newtonsoft.Json 库,很方便实用的一个Json库。具体用法就不详细讲了,Newtonsoft.Json下载地址:http://json.codeplex.com/
有了 Token 和 CodeString 就可以登录百度了。登录URL: https://passport.baidu.com/v2/api/?login
登录百度需要Post 一些参数,下面讲一下:
staticpage 登录后一个跳转地址
charset 大概是要求服务器返回数据的编码,没有仔细深究
token 就不用说了
tpl, apiver 上面说过了
tt 是时间戳
codestring 就是上面的获取的CodeString,如果没要求验证码,就为空。
isPhone 如果用手机号码登录则ture 否则为 false
safeflg,u 这两个没弄明白什么意思
username 就是百度帐号啦
password 是密码,明文,没有加密
verifycode 是验证码,如果没要求验证码,就为空。
mem_pass 应该是记住密码,一般固定为 on
ppui_logintime,callback 就固定为上面图片上的值就可以了
只要Post 上面的数据到 URL https://passport.baidu.com/v2/api/?login 就可以实现登录。
下面再看看登录后服务器返回的数据:
返回的数据中我们只要看 err_no 就可以了,err_no 是错误号,如果err_no=0 就说明登录成功,如果不是0那就登录失败。
下面是源码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using Newtonsoft.Json;
namespace LoginBAIDU
{
class Program
{
CookieCollection cookies = new CookieCollection();
CookieContainer cc = new CookieContainer();
string username = "asdkf1956@163.com";
string password = "test1956";
string Token = "";
string CodeString = "";
private string Accept = "*/*";
private string UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36";
private string Referer = "";
private string ContentType = "application/x-www-form-urlencoded";
private void Run()
{
string html = "";
//访问百度首页,获取 BAIDUID Cookie
GetPageByGet("http://www.baidu.com", Encoding.UTF8);
//获取 Token, CodeString
GetTokenAndCodeString();
//登录百度
Login(username, password);
PrintCookies();
}
/// <summary>
/// 获取 Token & CodeString
/// </summary>
private void GetTokenAndCodeString()
{
Console.WriteLine("---------------------------------Get Token--------------------------------------");
string url = string.Format("https://passport.baidu.com/v2/api/?getapi&tpl=ik&apiver=v3&tt={0}&class=login", Utility.GetCurrentTimeStamp());
string html = GetPageByGet(url, Encoding.UTF8);
Console.WriteLine(url);
ResultData result = JsonConvert.DeserializeObject<ResultData>(html);
if (result.ErrInfo.no == "0") {
Token = result.Data.Token;
CodeString = result.Data.CodeString;
}
Console.WriteLine("Token:{0}", Token);
Console.WriteLine("CodeString:{0}", CodeString);
Console.WriteLine("--------------------------------------------------------------------------------");
}
private void Login(string username, string password)
{
string loginUrl = "https://passport.baidu.com/v2/api/?login";
Dictionary<string, string> postData = new Dictionary<string, string>();
postData.Add("staticpage", "http://zhidao.baidu.com/static/html/v3Jump_bf2a8d6e.html");
postData.Add("charset", "GBK");
postData.Add("token", Token);
postData.Add("tpl", "ik");
postData.Add("apiver", "v3");
postData.Add("tt", Utility.GetCurrentTimeStamp().ToString());
postData.Add("codestring", "");
postData.Add("isPhone", "false");
postData.Add("safeflg", "0");
postData.Add("u", "http://www.baidu.com/");
postData.Add("username", username);
postData.Add("password", password);
postData.Add("verifycode", "");
postData.Add("mem_pass", "on");
postData.Add("ppui_logintime", "22429");
postData.Add("callback", "parent.bd__pcbs__7doo5q");
string html = GetPageByPost(loginUrl, postData, Encoding.UTF8);
Console.WriteLine(html);
}
/// <summary>
/// 打印 Cookies
/// </summary>
private void PrintCookies()
{
Console.WriteLine("---------------------------------Cookies----------------------------------------");
foreach (Cookie cookie in cookies) {
Console.WriteLine("{0}: {1} Domain: {2}", cookie.Name, cookie.Value, cookie.Domain);
}
Console.WriteLine("--------------------------------------------------------------------------------");
}
private void GetMyAsk()
{
string getAskUrl = "http://zhidao.baidu.com/uhome/ask";
string html = GetPageByGet(getAskUrl, Encoding.GetEncoding("GBK"));
Console.WriteLine(html);
}
/// <summary>
/// 以 Post 方式提交网页数据,获得服务器返回的数据
/// </summary>
/// <param name="url"> Url </param>
/// <param name="postData">Post 数据</param>
/// <param name="encoder">网页编码</param>
/// <returns>服务器返回的数据</returns>
private string GetPageByPost(string url, Dictionary<string, string> postData, Encoding encoder)
{
string html = "";
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);
webReq.CookieContainer = cc;
webReq.Method = "POST";
webReq.Accept = this.Accept;
webReq.UserAgent = this.UserAgent;
webReq.Referer = this.Referer;
Stream reqStream = null;
if (postData != null && postData.Count > 0) {
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> kv in postData) {
sb.Append(HttpUtility.UrlEncode(kv.Key));
sb.Append("=");
sb.Append(HttpUtility.UrlEncode(kv.Value));
sb.Append("&");
}
byte[] data = Encoding.UTF8.GetBytes(sb.ToString().TrimEnd('&'));
webReq.ContentType = ContentType;
webReq.ContentLength = data.Length;
reqStream = webReq.GetRequestStream();
reqStream.Write(data, 0, data.Length);
if (reqStream != null) {
reqStream.Close();
}
}
HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
cookies.Add(webResp.Cookies);
Stream stream = webResp.GetResponseStream();
StreamReader sr = new StreamReader(stream, encoder);
html = sr.ReadToEnd();
sr.Close();
stream.Close();
return html;
}
private string GetPageByGet(string url, Encoding encoder)
{
string html = "";
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);
webReq.CookieContainer = cc;
webReq.Method = "GET";
HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
cookies.Add(webResp.Cookies);
Stream stream = webResp.GetResponseStream();
StreamReader sr = new StreamReader(stream, encoder);
html = sr.ReadToEnd();
sr.Close();
stream.Close();
return html;
}
static void Main(string[] args)
{
new Program().Run();
Console.ReadKey();
}
}
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using Newtonsoft.Json;
namespace LoginBAIDU
{
class Program
{
CookieCollection cookies = new CookieCollection();
CookieContainer cc = new CookieContainer();
string username = "asdkf1956@163.com";
string password = "test1956";
string Token = "";
string CodeString = "";
private string Accept = "*/*";
private string UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36";
private string Referer = "";
private string ContentType = "application/x-www-form-urlencoded";
private void Run()
{
string html = "";
//访问百度首页,获取 BAIDUID Cookie
GetPageByGet("http://www.baidu.com", Encoding.UTF8);
//获取 Token, CodeString
GetTokenAndCodeString();
//登录百度
Login(username, password);
PrintCookies();
}
/// <summary>
/// 获取 Token & CodeString
/// </summary>
private void GetTokenAndCodeString()
{
Console.WriteLine("---------------------------------Get Token--------------------------------------");
string url = string.Format("https://passport.baidu.com/v2/api/?getapi&tpl=ik&apiver=v3&tt={0}&class=login", Utility.GetCurrentTimeStamp());
string html = GetPageByGet(url, Encoding.UTF8);
Console.WriteLine(url);
ResultData result = JsonConvert.DeserializeObject<ResultData>(html);
if (result.ErrInfo.no == "0") {
Token = result.Data.Token;
CodeString = result.Data.CodeString;
}
Console.WriteLine("Token:{0}", Token);
Console.WriteLine("CodeString:{0}", CodeString);
Console.WriteLine("--------------------------------------------------------------------------------");
}
private void Login(string username, string password)
{
string loginUrl = "https://passport.baidu.com/v2/api/?login";
Dictionary<string, string> postData = new Dictionary<string, string>();
postData.Add("staticpage", "http://zhidao.baidu.com/static/html/v3Jump_bf2a8d6e.html");
postData.Add("charset", "GBK");
postData.Add("token", Token);
postData.Add("tpl", "ik");
postData.Add("apiver", "v3");
postData.Add("tt", Utility.GetCurrentTimeStamp().ToString());
postData.Add("codestring", "");
postData.Add("isPhone", "false");
postData.Add("safeflg", "0");
postData.Add("u", "http://www.baidu.com/");
postData.Add("username", username);
postData.Add("password", password);
postData.Add("verifycode", "");
postData.Add("mem_pass", "on");
postData.Add("ppui_logintime", "22429");
postData.Add("callback", "parent.bd__pcbs__7doo5q");
string html = GetPageByPost(loginUrl, postData, Encoding.UTF8);
Console.WriteLine(html);
}
/// <summary>
/// 打印 Cookies
/// </summary>
private void PrintCookies()
{
Console.WriteLine("---------------------------------Cookies----------------------------------------");
foreach (Cookie cookie in cookies) {
Console.WriteLine("{0}: {1} Domain: {2}", cookie.Name, cookie.Value, cookie.Domain);
}
Console.WriteLine("--------------------------------------------------------------------------------");
}
private void GetMyAsk()
{
string getAskUrl = "http://zhidao.baidu.com/uhome/ask";
string html = GetPageByGet(getAskUrl, Encoding.GetEncoding("GBK"));
Console.WriteLine(html);
}
/// <summary>
/// 以 Post 方式提交网页数据,获得服务器返回的数据
/// </summary>
/// <param name="url"> Url </param>
/// <param name="postData">Post 数据</param>
/// <param name="encoder">网页编码</param>
/// <returns>服务器返回的数据</returns>
private string GetPageByPost(string url, Dictionary<string, string> postData, Encoding encoder)
{
string html = "";
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);
webReq.CookieContainer = cc;
webReq.Method = "POST";
webReq.Accept = this.Accept;
webReq.UserAgent = this.UserAgent;
webReq.Referer = this.Referer;
Stream reqStream = null;
if (postData != null && postData.Count > 0) {
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> kv in postData) {
sb.Append(HttpUtility.UrlEncode(kv.Key));
sb.Append("=");
sb.Append(HttpUtility.UrlEncode(kv.Value));
sb.Append("&");
}
byte[] data = Encoding.UTF8.GetBytes(sb.ToString().TrimEnd('&'));
webReq.ContentType = ContentType;
webReq.ContentLength = data.Length;
reqStream = webReq.GetRequestStream();
reqStream.Write(data, 0, data.Length);
if (reqStream != null) {
reqStream.Close();
}
}
HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
cookies.Add(webResp.Cookies);
Stream stream = webResp.GetResponseStream();
StreamReader sr = new StreamReader(stream, encoder);
html = sr.ReadToEnd();
sr.Close();
stream.Close();
return html;
}
private string GetPageByGet(string url, Encoding encoder)
{
string html = "";
HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(url);
webReq.CookieContainer = cc;
webReq.Method = "GET";
HttpWebResponse webResp = (HttpWebResponse)webReq.GetResponse();
cookies.Add(webResp.Cookies);
Stream stream = webResp.GetResponseStream();
StreamReader sr = new StreamReader(stream, encoder);
html = sr.ReadToEnd();
sr.Close();
stream.Close();
return html;
}
static void Main(string[] args)
{
new Program().Run();
Console.ReadKey();
}
}
}
运行结果: