задний план
Поскольку входная лотерея Nuggets дала Сяохаю вкус сладости (на самом деле, для птиц нет подушек для столов и значков), Сяохай присоединился к лотерейной команде, которая собирает руду каждый день.Теперь я вернулся во времена 100 →200 руд до освобождения, поэтому я решил оставить все на усмотрение программы, а javaer должен поговорить с программой
начать действовать
Прежде всего, мы создаем новый проект Springboot, зачем использовать Springboot? Поскольку Xiaohai — это серверная часть Java с годовым опытом работы, стек технологий — ctrl c, v + springboot. Хорошо, тогда мы добавляем @EnableScheduling, чтобы запускать запланированную задачу и выполнять наш код лотереи каждый день. В сочетании с @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) для отмены конфигурации источника данных по умолчанию, потому что нам не нужна поддержка базы данных, поэтому наши полки настроены и начинают писать бизнес.
/**
* @author lizhihai
* @date 2021/09/11
* 开启定时任务,取消springdatasource加载
*/
@EnableScheduling
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class MyTestProApplication {
public static void main(String[] args) {
SpringApplication.run(MyTestProApplication.class, args);
}
}
Войти Прощита
Все запросы на вход в лотерею Nuggets основаны на протоколе https и имеют сертификаты, поэтому не будем говорить больше, используйте HttpURLConnection для написания общего метода отправки запросов https и метода получения возвращаемого значения, здесь для справкиwoohoo.brief.com/afraid/848911place8…
/**
* 通用https请求方法 掘金是https协议有证书请求
*
* @param url
* @param method
* @return
* @throws Exception
*/
public String commnoReuqest(String url, String method,Cookies cookie) throws Exception {
URL serverUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();
conn.setRequestMethod(method);
conn.setRequestProperty("Content-type", "application/json");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36");
conn.setRequestProperty("Cookie", cookie.getValue());
//必须设置false,否则会自动redirect到重定向后的地址
conn.setInstanceFollowRedirects(false);
conn.connect();
String result = getReturn(conn);
return result;
}
/*请求url获取返回的内容*/
public static String getReturn(HttpURLConnection connection) throws IOException {
StringBuffer buffer = new StringBuffer();
//将返回的输入流转换成字符串
try (InputStream inputStream = connection.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);) {
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
String result = buffer.toString();
return result;
}
}
самородки API
Затем мы открываем знакомую F12, чтобы посмотреть, как выглядит запрос для Nuggets на вход в лотерею, ищем API и угадываем, что делает каждый запрос на основе URL, Далее мы записываем отсортированный API в константный класс. и Скопируйте файл cookie и инкапсулируйте методы входа, лотереи и запроса руды в соответствии с каждым URL-адресом и общим методом запроса. Получите cookie, получите URL-адрес, теперь мы можем выполнить операцию лотереи входа в программу, написать тест, чтобы попробовать, и запросить результат {"err_no":15001,"err_msg":"Вы выполнили вход- сегодня, не регистрироваться повторно","data":null} , хорошо, результат теста успешен получить√
public class Constans {
public static final String POST = "POST";
public static final String GET = "GET";
//URL
//签到
public static final String CHECK_IN = "https://api.juejin.cn/growth_api/v1/check_in";
//抽奖
public static final String DRAW = "https://api.juejin.cn/growth_api/v1/lottery/draw";
//查询剩余矿石
public static final String GET_CUR_POINT = "https://api.juejin.cn/growth_api/v1/get_cur_point";
}
/**
* 签到
*
* @throws Exception
*/
public boolean checkIn(Cookies cookie) throws Exception {
String response = commnoReuqest(Constans.CHECK_IN, Constans.POST,cookie);
logger.info("{}{}",cookie.getName(),response);
boolean hasSign=!response.contains("err_no":0");
if(hasSign){
sendHttps.sendToDingDing(cookie.getName()+response);
}
return hasSign;
}
/**
* 抽奖
*
* @throws Exception
*/
public void draw(Cookies cookie) throws Exception {
String response = commnoReuqest(Constans.DRAW, Constans.POST,cookie);
DrawResponce data= JSON.parseObject(response,new TypeReference<DrawResponce>(){});
String prizeName=data.getData().getLotteryName();
if(!"66矿石".equals(prizeName)&&!prizeName.contains("Bug")){
log.error("{}抽到好东西了{}!!!!!!,cookie.getName()+"抽到"+prizeName");
}
logger.info(response);
}
Расширяемость
Здесь Сяохай открыл трубу и привел маленького партнера, чтобы присоединиться к лотерейной команде, поэтому необходимо завершить операцию пакетной лотереи, и учитывая, что некоторые мелкие партнеры надеются использовать бесплатную лотерею каждый день, чтобы сохранить руду, а некоторые надеются привлечь лотерея каждый день. Итак, мы определяем класс перечисления с такими атрибутами, как имя, значение и allin, которые представляют имя друга, файл cookie-самородка друга и хочет ли друг участвовать в лотерее. Таким образом, мы можем проводить лотерею, просматривая значения перечисления.
//cookie 掘金的cookie据说有一个月有效期,挂了就再拷一个过来
public enum Cookies {
HAI1(true,"小海183","_ga=GA1.2.1296772436.1629686778; passport_csrf_token_default=f933ed7f9d24bfb06894114528a64af6; passport_csrf_token=f933ed7f9d24bfb06894114528a64af6; MONITOR_WEB_ID=aa936331-59e1-4607-8edf-84657bbc22cd; _gid=GA1.2.1269321208.1630996120; odin_tt=1bb7f242d137177d63dd9302d566ca5eac4c9fcb56b1dde948623c0efaf17cbecade967d875212a51b1c0e85f5643f2b08907c58b7b23435c0f866d83a18cf6e; passport_auth_status=0481add371299d2704126689380b9849%2C703a60ebb0e24b3a72db9bdc379e399d; passport_auth_status_ss=0481add371299d2704126689380b9849%2C703a60ebb0e24b3a72db9bdc379e399d; sid_guard=a6220a3e86f808bb214cbbe6d482a529%7C1631266482%7C5184000%7CTue%2C+09-Nov-2021+09%3A34%3A42+GMT; uid_tt=ccb35b269c8a75cb1dbd63c6d37a8a53; uid_tt_ss=ccb35b269c8a75cb1dbd63c6d37a8a53; sid_tt=a6220a3e86f808bb214cbbe6d482a529; sessionid=a6220a3e86f808bb214cbbe6d482a529; sessionid_ss=a6220a3e86f808bb214cbbe6d482a529; sid_ucp_v1=1.0.0-KDZkMGY3MDVmMzIyODI0MzU3Y2IyOWRjNGFmOGUxYTQwMGIwNTA3MWMKFwi93KCx4o2gBRCyzeyJBhiwFDgCQPEHGgJsZiIgYTYyMjBhM2U4NmY4MDhiYjIxNGNiYmU2ZDQ4MmE1Mjk; ssid_ucp_v1=1.0.0-KDZkMGY3MDVmMzIyODI0MzU3Y2IyOWRjNGFmOGUxYTQwMGIwNTA3MWMKFwi93KCx4o2gBRCyzeyJBhiwFDgCQPEHGgJsZiIgYTYyMjBhM2U4NmY4MDhiYjIxNGNiYmU2ZDQ4MmE1Mjk; n_mh=KF_8KclpLr_zR7cAEjb3RtZNBW4-HCCsXj4xdrmiLXE"),
HAI2(true,"小海176","MONITOR_WEB_ID=46e596ce-9ecc-4a89-992a-7c6a6e0c3481; _ga=GA1.2.1129485207.1631332210; _gid=GA1.2.1280463638.1631332210; passport_csrf_token_default=79180cb48bf4906a01362c777619a03e; passport_csrf_token=79180cb48bf4906a01362c777619a03e; passport_auth_status=26b44631a00ffda2ca525997e425471b%2C; passport_auth_status_ss=26b44631a00ffda2ca525997e425471b%2C; sid_guard=da5b5f8fa2be84a74656f9ed8f0f58de%7C1631332246%7C5184000%7CWed%2C+10-Nov-2021+03%3A50%3A46+GMT; uid_tt=369af9b9a6bd0a458166702eb1a9eb76; uid_tt_ss=369af9b9a6bd0a458166702eb1a9eb76; sid_tt=da5b5f8fa2be84a74656f9ed8f0f58de; sessionid=da5b5f8fa2be84a74656f9ed8f0f58de; sessionid_ss=da5b5f8fa2be84a74656f9ed8f0f58de; sid_ucp_v1=1.0.0-KDA2ODRmYTJmODZiOThjYjBjNDhjYjZjYzMwZjY0NzNhNzM1ODdhYmIKFwjnkrCFu4yWAxCWz_CJBhiwFDgCQPEHGgJsZiIgZGE1YjVmOGZhMmJlODRhNzQ2NTZmOWVkOGYwZjU4ZGU; ssid_ucp_v1=1.0.0-KDA2ODRmYTJmODZiOThjYjBjNDhjYjZjYzMwZjY0NzNhNzM1ODdhYmIKFwjnkrCFu4yWAxCWz_CJBhiwFDgCQPEHGgJsZiIgZGE1YjVmOGZhMmJlODRhNzQ2NTZmOWVkOGYwZjU4ZGU; n_mh=gY-EUdc0-atNYE3DFtWTsH7CHt0JMgKQkRnBimbpdn8; _gat=1"),
WU(true,"小吴","MONITOR_WEB_ID=da85199d-f4d8-434b-a709-6470a7f2ae08; _ga=GA1.2.1545343137.1631330098; _gid=GA1.2.1996029296.1631330098; passport_csrf_token_default=c95cd45eb0563c42a850d971f8f8d670; passport_csrf_token=c95cd45eb0563c42a850d971f8f8d670; passport_auth_status=46573bcc67d38f6c4202117b42f9b248%2C; passport_auth_status_ss=46573bcc67d38f6c4202117b42f9b248%2C; sid_guard=ed395050035826d1ea12953bd5728b05%7C1631330346%7C5184000%7CWed%2C+10-Nov-2021+03%3A19%3A06+GMT; uid_tt=4f23e928a63e23958189356b7349ddc1; uid_tt_ss=4f23e928a63e23958189356b7349ddc1; sid_tt=ed395050035826d1ea12953bd5728b05; sessionid=ed395050035826d1ea12953bd5728b05; sessionid_ss=ed395050035826d1ea12953bd5728b05; sid_ucp_v1=1.0.0-KDAzNjEzZDNkM2FmODRhNDIxY2E3ODQ4YzJkYjY4MDI5MzczNmFjZDYKFwjnr4CNvIyqBRCqwPCJBhiwFDgCQPEHGgJsZiIgZWQzOTUwNTAwMzU4MjZkMWVhMTI5NTNiZDU3MjhiMDU; ssid_ucp_v1=1.0.0-KDAzNjEzZDNkM2FmODRhNDIxY2E3ODQ4YzJkYjY4MDI5MzczNmFjZDYKFwjnr4CNvIyqBRCqwPCJBhiwFDgCQPEHGgJsZiIgZWQzOTUwNTAwMzU4MjZkMWVhMTI5NTNiZDU3MjhiMDU; n_mh=fCN8FMn4hIUuqN_fJo4Lf9qCwiFWUh01_NgRv1iwdfQ");
private String name;//名字
private String value;//cookie,自己上浏览器粘贴过来
private boolean isAllIn;//是否梭哈
Cookies(boolean isAllIn,String name, String value) {
this.isAllIn=isAllIn;
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public boolean isAllIn() {
return isAllIn;
}
public String getValue() {
return value;
}
}
задача на время
Дело здесь, в последнем шаге лотерейной задачи, давайте посмотрим на код, здесь нам не нужно беспокоиться о том, чтобы сломать знак на выходных, чтобы мы могли освободить руки для удаления приложения Nuggets. . эй эй
@Scheduled(cron = "0 1 0 * * ?")
public void excute() throws Exception {
logger.info("定时任务开始");
for(Cookies cookie:Cookies.values()){
boolean hasSign=checkIn(cookie);
if(hasSign) {continue;}
// 第一次免费抽奖
draw(cookie);
//还能抽就继续干
while(cookie.isAllIn()&&getCurPoint(cookie)>=200){
draw(cookie);
}
}
logger.info("执行结束");
}
Кстати
Здесь возврат API-интерфейса Nuggets завернут в один слой, и использовать maputils очень громоздко.Я рекомендую плагин идеи gsonformat, чтобы напрямую скопировать строку, возвращаемую запросом, для создания нашего класса ответа результата лотереи одним щелчком мыши, который Прекрасный.
@NoArgsConstructor
@Data
public class DrawResponce {
@JsonProperty("err_no")
private Integer errNo;
@JsonProperty("err_msg")
private String errMsg;
@JsonProperty("data")
private DataDTO data;
@NoArgsConstructor
@Data
public static class DataDTO {
@JsonProperty("id")
private Integer id;
@JsonProperty("lottery_id")
private String lotteryId;
@JsonProperty("lottery_name")
private String lotteryName;
@JsonProperty("lottery_type")
private Integer lotteryType;
@JsonProperty("lottery_image")
private String lotteryImage;
@JsonProperty("history_id")
private String historyId;
}
}
Робот DingTalk
Когда я попал сюда, то друг спросил меня. Я хочу знать, что делать, если я его нарисую. Может быть, я побежал в вашу компанию, чтобы посмотреть на вашу консоль и поискать log.info? Итак, я ссылаюсь (ctrl c+v) на эти две статьи51. Цао Цао/Java/526453…,блог woo woo woo.cn на.com/fugitive/afraid/…При стыковке DingTalk код не будет выкладываться Их достаточно много Я пристыковал своего группового робота DingTalk (метод проверки IP) Тогда я могу получать несколько сообщений DingTalk в двенадцать часов каждый день: Сяохай нарисовал 66 руд. Это было так неожиданно, я заплакала
наконец
Наконец: Это первый раз, когда новичок маленький java Xiaohai написал статью.Есть много наследственных операций ctrl cv, и большие парни могут просто смотреть на это для удовольствия. Исходный код выложен на гитхаб,Github.com/nicholas z Hi ...Если вы испытываете затруднения и хотите сыграть в лотерею бесплатно, вы можете отправить свое имя, аллин и куки в поле для комментариев в формате. Например (Николас Сяохай, Стад/Без Стад, "николас") я приглашу вас в группу, чтобы вы присоединились к лотерейной команде.