完整百度登录源代码(2015年1月27日更新)

上上个项目有个需求是获取百度文库与百度网盘资源,让我实现免费下载的功能。当时觉得不可能,现在觉得很简单。要获取百度相关信息肯定是需要模拟百度登录的,所以研究了下百度的登录,在项目中抽了登录代码出来,可以通过MAIN方法直接登录(LIB也是全的),源码中还包括了一些个人经验小谈,希望对朋友有些帮助。有任何问题可沟通讨论。

百度登录源码及LIB下载地址:http://download.csdn.net/detail/programmer_sir/8400495

整理后一共有两个类,一个是百度登录的类,一个是基础HTTP请求的类。

package org.baidu;


import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.htmlparser.Parser;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.util.NodeList;
import org.htmlparser.util.ParserException;

/**
 * 百度登录SERVICE.
 * @author 新昵称Belen
 * @version 1.0 2015-1-27整理。
 * @since 1.0
 */
public class BaiduLoginService {

	private BaiduConnectService bc = BaiduConnectService.getInstance();
	private static final String BAIDU_URL = "http://www.baidu.com";
	private static final String TOKEN_GET_URL = "https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&class=login&logintype=dialogLogin";
	private static final String LOGIN_POST_URL = "https://passport.baidu.com/v2/api/?login";
	private String username;
	private String password;
	private String verifycode;
	private String codestring;
	private String token;
	
	public BaiduLoginService(String username,String password,String verifycode,String codestring){
		this.username = username;
		this.password = password;
		this.verifycode = verifycode;
		this.codestring = codestring;
	}
	
	// test
	public static void main(String[] args) throws Exception{
		// 请确保你在www.baidu.com可以登录成功。
		new BaiduLoginService("百度用户名", "百度登录密码","","").login();
		// 下载百度文库。
//		new BaiduDownloadService("http://wenku.baidu.com/view/71ce3ec60c22590102029dd1.html").download();
	}
	
	public void login() throws Exception{
		System.out.println("准备登录 . Usename:"+username);
		// 预登录,获取cookie以便获取token.
		bc.execute(BAIDU_URL);
		this.initToken();
		System.out.println("正在登录。");
		HttpResponse response = bc.execute(LOGIN_POST_URL, produceFormEntity());
		String result = EntityUtils.toString(response.getEntity());
		String statusCode = this.substring(result, "error=", "'");
		System.out.println("百度返回的状态码:" + statusCode);
		// 自动识别验证码。
		// tools.autoCode(codestring);
		EntityUtils.consume(response.getEntity());
		System.out.println("--------------------------------");
		if(!checkLogin()){
			System.out.println("登录异常或频繁,需要验证码,codeString为:" + this.substring(result, "codestring=", "&"));
			System.out.println("登录结果:" + username + " 登录失败.");	
		}else{
			System.out.println("登录结果:" + " 登录成功.");
		}
	}
	
	public NodeList getNodeByName(String content,String tag,String name){
		Parser parser = Parser.createParser(content, "utf-8");
		AndFilter filter = new AndFilter(new TagNameFilter(tag),new HasAttributeFilter("name",name));
		try {
			return parser.parse(filter);
		} catch (ParserException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	// 登录POST参数
	private List<NameValuePair> produceFormEntity() throws UnsupportedEncodingException{
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		list.add(new BasicNameValuePair("tt", ""+System.currentTimeMillis()));
		list.add(new BasicNameValuePair("tpl", "mn"));
		list.add(new BasicNameValuePair("token", token));
		list.add(new BasicNameValuePair("isPhone", ""));
		list.add(new BasicNameValuePair("username", username));
		list.add(new BasicNameValuePair("password", password));
		list.add(new BasicNameValuePair("verifycode", verifycode));
		list.add(new BasicNameValuePair("codestring", codestring));
		return list;
	}
	
	private void initToken() throws Exception{
		System.out.println("获取百度Token...");
		HttpResponse response = bc.execute(TOKEN_GET_URL);
		String str = EntityUtils.toString(response.getEntity());
		Pattern pattern = Pattern.compile("token\" : \"(.*?)\"");
		Matcher matcher = pattern.matcher(str);
		if(matcher.find()){
			token = matcher.group(1);
		}
		System.out.println("Token已获取:"+token);
	}
	
	private boolean checkLogin() throws Exception{
		HttpResponse response = bc.execute(BAIDU_URL);
		boolean res = false;
		String content = EntityUtils.toString(response.getEntity());
		if(!content.contains("登录")){
			res = true;
		}
		EntityUtils.consume(response.getEntity());
		return res;
	}
	
	public static String substring(String str, String s1, String s2) {
		// 1、先获得0-s1的字符串,得到新的字符串sb1
		// 2、从sb1中开始0-s2获得最终的结果。
		try {
			StringBuffer sb = new StringBuffer(str);
			String sb1 = sb.substring(sb.indexOf(s1) + s1.length());
			return String.valueOf(sb1.substring(0, sb1.indexOf(s2)));
		} catch (StringIndexOutOfBoundsException e) {
			return str;
		}
	}
}

HTTP请求类:

package org.baidu;


import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

/**
 * HTTPCLIENT请求封装。
 * @author 新昵称Belen
 * @version 1.0 2015-1-27 整理。
 * @since 1.0
 */
@SuppressWarnings("deprecation")
public class BaiduConnectService {

	private CookieStore cookieStore = new BasicCookieStore();
	
	private BaiduConnectService(){}
	
	private static class BaiduConnectServiceContainer{
		private static BaiduConnectService bc = new BaiduConnectService();
	}
	
	public static BaiduConnectService getInstance(){
		System.out.println("初始化:BaiduConnectService.");
		return BaiduConnectServiceContainer.bc;
	}
	
	public HttpResponse execute(String url) throws Exception{
		return this.execute(url,null);
	}
	
	public HttpResponse execute(String url, List<NameValuePair> params) throws Exception{
		HttpClient httpClient = new DefaultHttpClient(
				new ThreadSafeClientConnManager());
		HttpResponse response = null;
		HttpUriRequest request = null;
		if (params != null) {
			HttpPost httpPost = new HttpPost(url);
			try {
				HttpEntity postBodyEnt = new UrlEncodedFormEntity(params);
				httpPost.setEntity(postBodyEnt);
			} catch (Exception e) {
				e.printStackTrace();
			}
			request = httpPost;
		} else {
			HttpGet httpGet = new HttpGet(url);
			request = httpGet;
		}
		HttpContext localContext = new BasicHttpContext();
		localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
		response = httpClient.execute(request, localContext);
		System.out.println("[HTTP状态码:" + response.getStatusLine().getStatusCode() + "]" + "-->Request URL:" + url);
		return response;
	}

	public CookieStore getCookieStore() {
		return cookieStore;
	}

	public void setCookieStore(CookieStore cookieStore) {
		this.cookieStore = cookieStore;
	}
}

运行MAIN方法后打印结果:

初始化:BaiduConnectService.
准备登录 . Usename:sir_belen
[Status:200]-->Request URL:http://www.baidu.com
获取百度Token...
[Status:200]-->Request URL:https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&class=login&logintype=dialogLogin
Token已获取:389d692e3022eac76a99365ba25949bd
正在登录。
[Status:200]-->Request URL:https://passport.baidu.com/v2/api/?login
百度返回的状态码:0
--------------------------------
[Status:200]-->Request URL:http://www.baidu.com
登录结果: 登录成功.
若你要做模拟百度登录我这里分享一点我个人的想法。

1.你必须要准备一个HTTP抓包工具,你可以用火狐的firebug,也可以用HttpWatch,个人比较推荐后者。
2.模拟互联网的网站登录或表单请求,你肯定要了解它们登录的参数,这个过程是痛苦的,多看,多想,多试吧。
3.现在apache下有2个Httpclient可以用,推荐使用最新的Httpclient Core.

评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值