出处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);
- }
- }
- 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();
- }
- }
- }
- }
就这么多了,不保证百度后台升级后程序会一直有效。