Java實現百度貼吧自動簽到器

   轉載請聲明出處http://blog.csdn.net/zhongkejingwang/article/details/39995909

   前段時間經常逛貼吧,每次都要手動簽到,有時候也會忘記簽到,很麻煩。於是就想用Java寫個自動簽到的工具並部署到實驗室的服務器上,這樣就可以常年自動簽到了。於是就有了這篇文章,權當玩玩。

  看一下程序的執行情況:

   將此程序放到服務器後臺運行就可以了,不用再擔心斷籤~   



   要簽到首先要登錄然後再獲取貼吧頁面裏的簽到鏈接。由於Java自帶的http的API使用起來很不方便,這裏使用的是Apache的httpclient(只用到了三個jar包,後面會提供下載),用post方法提交表單數據即可,關於表單的item參數可以用chrome瀏覽器抓包分析一下(按F12)。登錄地址選擇百度的手機網頁端:http://wappass.baidu.com/passport/login這個地址,這樣的話服務器端識別爲手機簽到,可以加分。在代碼中將用戶名和密碼提交到這個地址即可,在去年的時候抓包分析過這個頁面提交的數據還是明文的....現在已經升級了,網頁是經過加密後提交的密碼,不過明文提交還是可以登錄。


   登錄完了需要獲取貼吧首頁中用戶關注的所有貼吧,在這個地址http://tieba.baidu.com/mo,獲取網頁特定內容需要用到html解析工具,這裏使用的是Jsoup,可以在這裏看使用教程http://www.open-open.com/jsoup/


  獲取到關注貼吧的首頁然後把該貼吧的html頁面拉下來一份,檢索看看有沒有包含“sign”字符串,沒有表示已經簽到了;有則獲取對應的簽到地址,訪問改地址即可簽到成功。


  關於添加依賴包:在eclipse中右鍵工程—>屬性—>Java 構建路徑—>庫(L)裏添加外部JAR,就可以了。


  關於怎麼打包成可執行的jar包:這裏有依賴的jar包,建議將依賴的jar包一塊打包進去,可以使用eclipse打包,具體步驟:

右鍵工程—>導出—>Java—>可運行的jar包,點擊下一步,在接下來的選項中選擇Package required libraries into generated JAR:

                       

這樣就可以很方便的把jar包上傳到服務器執行了。否則手動打包需要寫MANIFEST.MF清單文件,指定Class-Path,指向所有依賴包,否則運行時找不到依賴包,比較麻煩。所以還是建議用eclipse打包吧。。。


  過程講完了可以講代碼了。寫一個SignUpTool接口:

package com.jingchen.util;

public interface SignUpTool {
    /**
     * 用戶登錄
     * 
     * @param username
     *            用戶名
     * @param passwd
     *            密碼
     * @return 登錄成功返回true,失敗則返回false
     */
    boolean login(String username, String passwd);

    /**
     * 簽到
     * 
     * @return 簽到成功返回true,失敗則返回falses
     */
    boolean signUp();
}
  接口包含了登錄和簽到方法,此接口不同的實現可以登錄不同的網站。

寫一個HttpUtil,封裝post和get操作:

package com.jingchen.util;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
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.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;

public class HttpUtil {
    private HttpClient mHttpClient;
    private CookieStore mCookieStore;
    private HttpContext mContext;
    private HttpPost post;
    private HttpGet get;

    public HttpUtil() {
	mHttpClient = new DefaultHttpClient();
	mCookieStore = new BasicCookieStore();
	mContext = new BasicHttpContext();
    }

    public HttpResponse post(String url, HttpEntity he)
	    throws ClientProtocolException, IOException {
	post = new HttpPost(url);
	post.setEntity(he);
	mContext.setAttribute(ClientContext.COOKIE_STORE, mCookieStore);
	HttpResponse hr = mHttpClient.execute(post, mContext);
	return hr;
    }

    public String get(String url) throws ClientProtocolException, IOException {
	String result = null;
	get = new HttpGet(url);
	HttpResponse hr = mHttpClient.execute(get, mContext);
	result = EntityUtils.toString(hr.getEntity());
	return result;
    }
}


實現SignUpTool接口的BaiduSignUp:

package com.jingchen.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * 用於登錄百度貼吧賬號並簽到的類
 * 
 * @author jingchen
 * 
 */
public class BaiduSignUp implements SignUpTool {
    // 登錄鏈接
    private String mLoginUrl = null;
    // 登錄後跳轉的頁面
    private String mIndexUrl = null;
    // 獲取網頁中的相對路徑拼接上這個頭部構成完整請求路徑
    private String mUrlHead = null;
    // 是否需要驗證碼
    private boolean isAuth = false;

    private HttpUtil httpUtil;

    // 關注的貼吧
    private List<String> mLikeBars;
    // 關注的貼吧首頁
    private List<String> mLikeBarsUrls;

    public BaiduSignUp() {
	mLikeBars = new ArrayList<String>();
	mLikeBarsUrls = new ArrayList<String>();
	httpUtil = new HttpUtil();
	mLoginUrl = "http://wappass.baidu.com/passport/login";
	mIndexUrl = "http://tieba.baidu.com/mo";
	mUrlHead = "http://tieba.baidu.com";
    }

    public boolean login(String username, String passwd) {
	isAuth = false;
	mLikeBars.clear();
	mLikeBarsUrls.clear();
	print("login...");
	List<NameValuePair> params = new ArrayList<NameValuePair>();
	params.add(new BasicNameValuePair("username", username));
	params.add(new BasicNameValuePair("password", passwd));
	HttpEntity he;
	try {
	    he = new UrlEncodedFormEntity(params, "UTF-8");
	    HttpResponse hr = httpUtil.post(mLoginUrl, he);
	    String firstresult = EntityUtils.toString(hr.getEntity());
	    if (firstresult.contains("verifycode")) {
		// 在異地登錄或者登錄頻繁會出現驗證碼
		isAuth = true;
		print("需要驗證碼");
		return false;
	    } else if (firstresult.contains("error_area")) {
		print("密碼錯誤");
		return false;
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	    return false;
	}
	print("登錄成功");
	return true;
    }

    public boolean signUp() {
	if (isAuth) {
	    print("需要驗證碼");
	    return false;
	}
	print("signUp...");
	if (mLikeBars.size() != 0) {
	    mLikeBars.clear();
	    mLikeBarsUrls.clear();
	}
	if (!getLikeBars())
	    return false;
	try {
	    for (int i = 0; i < mLikeBars.size(); i++) {
		String barview = getWebContent(mLikeBarsUrls.get(i));
		if (!barview.contains("sign"))
		    print(mLikeBars.get(i) + "已簽到");
		else {
		    Elements signurl = Jsoup.parse(barview)
			    .getElementsByAttributeValueMatching("href",
				    ".*sign.*");
		    getWebContent(mUrlHead + signurl.attr("href"));
		    print(mLikeBars.get(i) + "簽到成功");
		}
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	    print("fail in signUp!");
	    return false;
	}
	return true;
    }

    /**
     * 獲取關注的貼吧
     * 
     * @return
     */
    private boolean getLikeBars() {
	print("getLikeBars...");
	String indexresult = getWebContent(mIndexUrl);
	if (indexresult == null)
	    return false;
	Document document = Jsoup.parse(indexresult);
	Elements likebars = document.select("div.my_love_bar a");
	for (Element e : likebars) {
	    mLikeBarsUrls.add(mUrlHead + e.attr("href"));
	    mLikeBars.add(e.text());
	}
	if (mLikeBars.size() == 0)
	    return false;
	return true;
    }

    /**
     * 獲取網頁內容
     * 
     * @param url
     *            鏈接地址
     * @return 網頁內容
     */
    private String getWebContent(String url) {
	print("getWebContent...");
	String result = null;
	try {
	    result = httpUtil.get(url);
	} catch (Exception e) {
	    e.printStackTrace();
	    return null;
	}
	return result;
    }

    public void print(String s) {
	System.out.println(s);
    }
}
  包含main方法的主類:

package com.jingchen.main;

import com.jingchen.util.BaiduSignUp;
import com.jingchen.util.SignUpTool;

public class MainClass {
    public static String username = "******";
    public static String passwd = "******";
    public static int mInterval = 30;

    public static void main(String[] args) {
	boolean isSignup = false;
	boolean isLogin = false;
	SignUpTool tool = new BaiduSignUp();
	// SignUpTool tool = new BBSLogin();
	while (true) {
	    try {
		isLogin = tool.login(username, passwd);
		isSignup = tool.signUp();
		if (isLogin && isSignup) {
		    // 簽到成功則三小時後再簽到
		    System.out.println("continue after three hours...");
		    Thread.sleep(3 * 60 * 60 * 1000);
		} else {
		    // 簽到失敗則30分鐘後再次簽到
		    System.out.println("continue after " + mInterval
			    + " minites...");
		    Thread.sleep(mInterval * 60 * 1000);
		}
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}
    }

}
  每次簽到前都先登錄,簽到失敗則等半小時再嘗試,簽到成功則等待3小時再次簽到。將用戶名和密碼填上就可以了。

就這麼多了,不保證百度後臺升級後程序會一直有效。


源碼下載

    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章