zl程序教程

您现在的位置是:首页 >  Java

当前栏目

java签到百度贴吧

2023-02-18 16:41:07 时间

获取百度贴吧的BDUSS

在电脑端登录百度贴吧,按F12进入开发者控制台,点击Application

找到BDUSS,记录当中的值

申请Server酱中的Key并且绑定微信

代码如下

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>TiebaSignIn</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>TiebaSignIn</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.2.3</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.12</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.62</version>
    </dependency>
  </dependencies>

  <build>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
        <plugin>
          <artifactId>maven-site-plugin</artifactId>
          <version>3.7.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-project-info-reports-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
package com.ljfchtcc.domain;

/**
 * 存入用户所填写的BDUSS
 * @author LiYu
 * @Time 2020-11-23
 */
public class Cookie {
    private static final Cookie cookie = new Cookie();
    private String BDUSS;
    private Cookie(){};

    public static Cookie getInstance() {
        return cookie;
    }

    public String getBDUSS() {
        return BDUSS;
    }

    public void setBDUSS(String BDUSS) {
        this.BDUSS = BDUSS;
    }
    public String getCookie() {
        return "BDUSS="+BDUSS;
    }
}
package com.ljfchtcc.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * 对字符串进行加密
 * @author LiYu
 * @Time 2020-11-23
 */
public class Encryption {
    /** 获取日志记录器对象 */
    private static final Logger LOGGER = LoggerFactory.getLogger(Encryption.class);

    /**
     * 对字符串进行 MD5加密
     * @param str 传入一个字符串
     * @return String 加密后的字符串
     * @author LiYu
     * @Time 2020-11-23
     */
    public static String enCodeMd5(String str){
        try{
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes("UTF-8"));
            // digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
            //一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)

            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e){
            LOGGER.error("字符串进行MD5加密错误 -- " + e);
            return "";
        }
    }
}
package com.ljfchtcc.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ljfchtcc.domain.Cookie;

/**
 * 封装的网络请求请求工具类
 * @author LiYu
 * @Time 2020-11-23
 */
public class Request {
    /** 获取日志记录器对象 */
    private static final Logger LOGGER = LoggerFactory.getLogger(Request.class);
    /** 获取Cookie对象 */
    private static Cookie cookie = Cookie.getInstance();
    private Request(){};

    /**
     * 发送get请求
     * @param url 请求的地址,包括参数
     * @return JSONObject
     * @author LiYu
     * @Time 2020-11-23
     */
    public static JSONObject get(String url){
        RequestConfig defaultConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
        HttpClient client = HttpClients.custom().setDefaultRequestConfig(defaultConfig).build();

        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("connection","keep-alive");
        httpGet.addHeader("Content-Type","application/x-www-form-urlencoded");
        httpGet.addHeader("charset","UTF-8");
        httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36");
        httpGet.addHeader("Cookie",cookie.getCookie());
        HttpResponse resp = null;
        String respContent = null;
        try{
            resp = client.execute(httpGet);
            HttpEntity entity=null;
            if(resp.getStatusLine().getStatusCode()<400){
                entity = resp.getEntity();
            } else{
                entity = resp.getEntity();
            }
            respContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e){
            LOGGER.info("get请求错误 -- "+e);
        } finally {
            return JSONObject.parseObject(respContent);
        }
    }

    /**
     * 发送post请求
     * @param url 请求的地址
     * @param body 携带的参数
     * @return JSONObject
     * @author LiYu
     * @Time 2020-11-23
     */
    public static JSONObject post(String url , String body){
        StringEntity entityBody = new StringEntity(body,"UTF-8");
        RequestConfig defaultConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
        HttpClient client = HttpClients.custom().setDefaultRequestConfig(defaultConfig).build();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("connection","keep-alive");
        httpPost.addHeader("Host","tieba.baidu.com");
        httpPost.addHeader("Content-Type","application/x-www-form-urlencoded");
        httpPost.addHeader("charset","UTF-8");
        httpPost.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36");
        httpPost.addHeader("Cookie",cookie.getCookie());
        httpPost.setEntity(entityBody);
        HttpResponse resp = null;
        String respContent = null;
        try{
            resp = client.execute(httpPost);
            HttpEntity entity=null;
            if(resp.getStatusLine().getStatusCode()<400){
                entity = resp.getEntity();
            } else{
                entity = resp.getEntity();
            }
            respContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e){
            LOGGER.info("post请求错误 -- "+e);
        }
        finally {
            return JSONObject.parseObject(respContent);
        }
    }
}
package com.ljfchtcc;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ljfchtcc.domain.Cookie;
import com.ljfchtcc.util.Encryption;
import com.ljfchtcc.util.Request;
import java.util.*;

/**
 * 程序运行开始的地方
 * @author LiYu
 * @Time 2020-11-23
 */
public class Run
{
    /** 获取日志记录器对象 */
    private static final Logger LOGGER = LoggerFactory.getLogger(Run.class);
    /** 贴吧BDUSS */
    private static final String BDUSS = "刚刚保存的BDUSS";
    /** Server酱KEY */
    private static final String SCKEY = "刚刚申请的KEY";

    /** 获取用户所有关注贴吧 */
    String LIKE_URL = "https://tieba.baidu.com/mo/q/newmoindex";
    /** 获取用户的tbs */
    String TBS_URL = "http://tieba.baidu.com/dc/common/tbs";
    /** 贴吧签到接口 */
    String SIGN_URL = "http://c.tieba.baidu.com/c/c/forum/sign";


    /** 存储用户所关注的贴吧 */
    private List<String> follow = new ArrayList<>();
    /** 签到成功的贴吧列表 */
    private static List<String>  success = new ArrayList<>();
    /** 用户的tbs */
    private String tbs = "";
    /** 用户所关注的贴吧数量 */
    private static Integer followNum = 201;
    public static void main( String[] args ){
        Cookie cookie = Cookie.getInstance();
        // 存入Cookie,以备使用
        cookie.setBDUSS(BDUSS);
        Run run = new Run();
        run.getTbs();
        run.getFollow();
        run.runSign();
        LOGGER.info("共 {} 个贴吧 - 成功: {} - 失败: {}",followNum,success.size(),followNum-success.size());
        run.send(SCKEY);
    }

    /**
     * 进行登录,获得 tbs ,签到的时候需要用到这个参数
     * @author LiYu
     * @Time 2020-11-23
     */
    public void getTbs(){
        try{
            JSONObject jsonObject = Request.get(TBS_URL);
            if("1".equals(jsonObject.getString("is_login"))){
                LOGGER.info("获取tbs成功");
                tbs = jsonObject.getString("tbs");
            } else{
                LOGGER.warn("获取tbs失败 -- " + jsonObject);
            }
        } catch (Exception e){
            LOGGER.error("获取tbs部分出现错误 -- " + e);
        }
    }

    /**
     * 获取用户所关注的贴吧列表
     * @author LiYu
     * @Time 2020-11-23
     */
    public void getFollow(){
        try{
            JSONObject jsonObject = Request.get(LIKE_URL);
            LOGGER.info("获取贴吧列表成功");
            JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("like_forum");
            followNum = jsonArray.size();
            // 获取用户所有关注的贴吧
            for (Object array : jsonArray) {
                if("0".equals(((JSONObject) array).getString("is_sign"))){
                    // 将为签到的贴吧加入到 follow 中,待签到
                    System.out.println(((JSONObject) array).getString("forum_name")+"吧待签到");
                    follow.add(((JSONObject) array).getString("forum_name"));
                } else{
                    // 将已经成功签到的贴吧,加入到 success
                    System.out.println(((JSONObject) array).getString("forum_name")+"吧已签到");
                    success.add(((JSONObject) array).getString("forum_name"));
                }
            }
        } catch (Exception e){
            LOGGER.error("获取贴吧列表部分出现错误 -- " + e);
        }
    }

    /**
     * 开始进行签到,每一轮性将所有未签到的贴吧进行签到,一共进行5轮,如果还未签到完就立即结束
     * 一般一次只会有少数的贴吧未能完成签到,为了减少接口访问次数,每一轮签到完等待1分钟,如果在过程中所有贴吧签到完则结束。
     * @author LiYu
     * @Time 2020-11-23
     */
    public void runSign(){
        // 当执行 5 轮所有贴吧还未签到成功就结束操作
        Integer flag = 5;
        try{
            while(success.size()<followNum&&flag>0){
                LOGGER.info("-----第 {} 轮签到开始-----", 5 - flag + 1);
                LOGGER.info("还剩 {} 贴吧需要签到", followNum - success.size());
                Iterator<String> iterator = follow.iterator();
                while(iterator.hasNext()){
                    String s = iterator.next();
                    String body = "kw="+s+"&tbs="+tbs+"&sign="+ Encryption.enCodeMd5("kw="+s+"tbs="+tbs+"tiebaclient!!!");
                    JSONObject post = Request.post(SIGN_URL, body);
                    if("0".equals(post.getString("error_code"))){
                        iterator.remove();
                        success.add(s);
                        LOGGER.info(s + ": " + "签到成功");
                    } else {
                        LOGGER.warn(s + ": " + "签到失败");
                    }
                }
                if (success.size() != followNum){
                    // 为防止短时间内多次请求接口,触发风控,设置每一轮签到完等待 5 分钟
                    Thread.sleep(1000 * 60 * 5);
                    /**
                     * 重新获取 tbs
                     * 尝试解决以前第 1 次签到失败,剩余 4 次循环都会失败的错误。
                     */
                    getTbs();
                }
                flag--;
            }
        } catch (Exception e){
            LOGGER.error("签到部分出现错误 -- " + e);
        }
    }

    /**
     * 发送运行结果到微信,通过 server 酱
     * @param sckey
     * @author LiYu
     * @Time 2020-11-23
     */
    public void send(String sckey){
        /** 将要推送的数据 */
        String text = "总: "+ followNum + " - ";
        text += "成功: " + success.size() + " 失败: " + (followNum - success.size());
        String desp = "共 "+ followNum + " 贴吧\n\n";
        desp += "成功: " + success.size() + " 失败: " + (followNum - success.size());
        String body = "text="+text+"&desp="+"TiebaSignIn运行结果\n\n"+desp;
        StringEntity entityBody = new StringEntity(body,"UTF-8");
        HttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost("https://sc.ftqq.com/"+sckey+".send");
        httpPost.addHeader("Content-Type","application/x-www-form-urlencoded");
        httpPost.setEntity(entityBody);
        HttpResponse resp = null;
        String respContent = null;
        try{
            resp = client.execute(httpPost);
            HttpEntity entity=null;
            if(resp.getStatusLine().getStatusCode()<400){
                entity = resp.getEntity();
            } else{
                entity = resp.getEntity();
            }
            respContent = EntityUtils.toString(entity, "UTF-8");
            LOGGER.info("server酱推送正常");
        } catch (Exception e){
            LOGGER.error("server酱发送失败 -- " + e);
        }
    }
}

运行效果如下