作者 aosfather
版本 1.0
sina微博 @aosfather
百度有很多服務,但這些服務都是必須要登錄才能使用,對於個人用戶倒好,但對於一些想寫點工具的個人和公司來說,就是一大障礙。而且現在網上能搜到的都是以前的文章,百度的API已經改過幾個版本了,現成的代碼基本都無效了。於是本人追蹤了百度的登錄請求,並試驗多次終於成功了。
百度登錄過程
-
請求https://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=true獲 取一個cookie
-
再次請求https://passport.baidu.com/v2/api/? getapi&class=login&tpl=mn&tangram=true獲取token,解析返回的數據,通過正則表 達式匹配("bdPass.api.params.login_token='(.*?)';")得到token.
-
發送登錄請求https://passport.baidu.com/v2/api/?login
-
記錄下BAIDUID、BDUSS、SSUDB,用於發送(另起httpclient)調用其它服務的
URL時候用。
代碼示例
代碼基於httpclient3
HttpClient httpClient = new HttpClient();
httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
//獲取一個cookie
GetMethod httpget = new GetMethod("https://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=true");
httpClient.executeMethod(httpget);
//獲取token
String token=null;
GetMethod getToken=new GetMethod("https://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=true");
httpClient.executeMethod(getToken);
Pattern tokenp=Pattern.compile("bdPass.api.params.login_token='(.*?)';");
Matcher m=tokenp.matcher(getToken.getResponseBodyAsString());
if(m.find()){
token=m.group(1);
}
//登錄
PostMethod httppost = new PostMethod("https://passport.baidu.com/v2/api/?login");
//構造登錄請求post的數據
httppost.setParameter("tpl", "mn");
httppost.setParameter("callback","parent.bdPass.api.login._postCallback");
httppost.setParameter("staticpage","https://passport.baidu.com/v3Jump.html");
httppost.setParameter("codestring","");
httppost.setParameter("ppui_logintime", "10484");
httppost.setParameter("u", "");
httppost.setParameter("charset","utf-8");
httppost.setParameter("index","0");
httppost.setParameter("password","***************");//密碼
httppost.setParameter("loginType","1");
httppost.setParameter("safeflg", "0");
httppost.setParameter("isphone", "false");
httppost.setParameter("username", "aosfather");//登錄用戶名
httppost.setParameter("verifycode", "");
httppost.setParameter("mem_pass", "on");
httppost.setRequestHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)");
httppost.setRequestHeader("Host","passport.baidu.com");
httppost.setParameter("token",token);//剛纔解析出來的token。
httpClient.executeMethod(httppost);
//獲取cookie中的值
Cookie[] cookies=httpClient.getState().getCookies();
String tmpcookies= "";//;)原諒我吧,這只是個測試例子,編譯器會翻譯成StringBuilder的。
for(Cookie c:cookies){
if(c.getName().equals("BAIDUID")||c.getName().equals("BDUSS")||c.getName().equals("SSUDB"))
tmpcookies += c.toString()+";";
}
//-------------------華麗的分割線,下面的代碼用於驗證,訪問百度的其它服務時候,是否認爲我們已經登錄了--------------//
//驗證一下,訪問baidu的網站,你會發現已經登錄了。
//另建一個httpclient
HttpClient client=new HttpClient();
//------------訪問百度-------------//
GetMethod getMethod = new GetMethod("http://www.baidu.com");
getMethod.setRequestHeader("cookie", tmpcookies);//設置cookie值,將登錄返回的信息設定進去
int statusCode = client.executeMethod(getMethod) ;
if (statusCode != HttpStatus.SC_OK)
{
System.err.println("Method failed: "
+ getMethod.getStatusLine());
}
//將返回信息打印出來,你會看到找到賬號信息,就說明百度已經認可你登錄了。否則返回的字符中有“登錄 註冊”的字眼。
byte[] responseBody = getMethod.getResponseBody();
System.out.println(new String(responseBody));