百度登陸協議分析

登陸百度前須要先獲取必要的Cookies 和一些參數 Token, CodeStringhtml

首先,要獲取的是 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=loginweb

URL 地址其中幾個參數的意義:
tpl 不知道是作什麼用,一是固定的寫 ik 就能夠了
apiver 的值是固定的 API的版本號
tt 是時間戳 
class 動做類別,登陸時是login,註冊百度賬號時是reg
服務器會返回 Json 結構的數據,其中包含了 Token 和 CodeString:
{
    "errInfo": {
        "no": "0"
    },
    "data": {
        "rememberedUserName": "",
        "codeString": "",
        "token": "d45f26cf74aa65c3088f699b8791f9eb",
        "cookie": "1"
    }
}
codeString 通常爲空,若是不爲空,那麼登陸時就須要驗證碼。因此能夠根據這個值進行判斷登陸時是須要驗證碼。獲取驗證碼的URL:

https://passport.baidu.com/cgi-bin/genimage? //?後跟CodeString的值json

解析 Json 有不少方法,若是使用 C# 能夠使用 Newtonsoft.Json 庫,很方便實用的一個Json庫。具體用法就不詳細講了,Newtonsoft.Json下載地址: http://json.codeplex.com/
 

有了 Token 和 CodeString 就能夠登陸百度了。登陸URL: https://passport.baidu.com/v2/api/?loginapi

登陸百度須要Post 一些參數,下面講一下:
staticpage 登陸後一個跳轉地址
charset 大概是要求服務器返回數據的編碼,沒有仔細深究
token 就不用說了
tpl, apiver 上面說過了
tt 是時間戳
codestring 就是上面的獲取的CodeString,若是沒要求驗證碼,就爲空。
isPhone 若是用手機號碼登陸則ture 不然爲 false
safeflgu 這兩個沒弄明白什麼意思
username 就是百度賬號啦
password 是密碼,明文,沒有加密
verifycode 是驗證碼,若是沒要求驗證碼,就爲空。
mem_pass 應該是記住密碼,通常固定爲 on
ppui_logintimecallback 就固定爲上面圖片上的值就能夠了

 

 

只要Post 上面的數據到 URL https://passport.baidu.com/v2/api/?login 就能夠實現登陸。

 

下面再看看登陸後服務器返回的數據:

返回的數據中咱們只要看 err_no 就能夠了,err_no 是錯誤號,若是err_no=0 就說明登陸成功,若是不是0那就登陸失敗。 服務器

下面是源碼:cookie

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< stringstring> postData =  new Dictionary< stringstring>();
            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< stringstring> 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< stringstring> 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();
        }
    }

} app

 

運行結果:
相關文章
相關標籤/搜索