分析页面 首先所有的自动化都是拟人操作,只需要模拟出正常的签到步骤并定时重复即可满足需求。
获取登录状态
- 签到总要知道是哪个用户签的嘛,所以所有的请求都要带上用户登录标识,也就是在header中添加对应的cookie
- 如何获取cookie呢,这里看了下掘金的登录请求还比较麻烦,对熟悉爬虫的同学可能小菜一碟,对后端来说虽然能做但是本着投入时间与收益的原则,我毅然决然的选择绕过登录,直接拦截请求把request header的cookie复制出来。
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hrACs4W2-1665316799526)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/88660b222a284cc18302a4679346a624~tplv-k3u1fbpfcp-zoom-1.image “image.png”)]
- 没有登录逻辑的话等cookie失效签到请求会返回请登录,这里话通过邮箱提醒更换cookie也是可以接受的
- 随便从网上找一个http方法即可
创建脚手架
pom里直接引入springboot-web、springboot-mail、lombok、fastjson,版本管理直接继承下spring-boot-dependencies。
org.springframework.boot
spring-boot-dependencies
2.4.3
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-mail
org.projectlombok
lombok
com.alibaba
fastjson
1.2.41
启动类上添加@EnableScheduling注解开启定时任务
@EnableScheduling
@SpringBootApplication
public class SignApplication {public static void main(String[] args) {
SpringApplication.run(SignApplication.class, args);
}
}
整体的骨架就这么简单。
通用http方法
public static String commonReuqest(String url, String method, String 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);
//必须设置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;
}
}
封装成一个util类,入口加上cookie即可,这里直接从网上找了个方法。
邮箱逻辑
- 如何开启smtp邮箱服务就不说了,这里直接贴一下教程https://blog.csdn.net/weixin_46822367/article/details/123893527
- yml配置里需要配置上必要信息,授权码按照上述博客中的步骤获取。
spring:
mail:
host: smtp.qq.com
#发送者邮箱
username:
#申请到的授权码
password:
#端口号465或587
port: 587
#默认的邮件编码为UTF-8
default-encoding: UTF-8
#其他参数
properties:
mail:
#配置SSL 加密工厂
smtp:
ssl:
#本地测试,先放开ssl
enable: false
required: false
#开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误
debug: true
- 邮箱业务类
@Service
@Slf4j
public class SendMailServiceImpl implements SendMailService {@Autowired
private JavaMailSender javaMailSender;
@Value("${spring.mail.username}")
private String sendMailer;
public void checkMail(MailRequest mailRequest) {
Assert.notNull(mailRequest,"邮件请求不能为空");
Assert.notNull(mailRequest.getSendTo(), "邮件收件人不能为空");
Assert.notNull(mailRequest.getSubject(), "邮件主题不能为空");
Assert.notNull(mailRequest.getText(), "邮件收件人不能为空");
}@Override
public void sendMail(MailRequest mailRequest) {
SimpleMailMessage message = new SimpleMailMessage();
checkMail(mailRequest);
//邮件发件人
message.setFrom(sendMailer);
//邮件收件人 1或多个
message.setTo(mailRequest.getSendTo().split(","));
//邮件主题
message.setSubject(mailRequest.getSubject());
//邮件内容
message.setText(mailRequest.getText());
//邮件发送时间
message.setSentDate(new Date());
//JavaMailSender javaMailSender = new JavaMailSenderImpl();
javaMailSender.send(message);
log.info("发送邮件成功:{}->{}",sendMailer,mailRequest.getSendTo());
}}
JavaMailSender为spring-boot-starter-mail依赖中封装好的业务类,yml中添加对应的配置该类会被注入到容器中。
签到请求
@Slf4j
@Service
public class ActionService {//签到
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";
@Value("${spring.mail.username}")
private String username;
@Autowired
SendMailService sendMailService;
/**
* 签到
*/
public void checkIn(String cookie) throws Exception {
String response = BaseRequest.commonReuqest(CHECK_IN, "POST", cookie);
log.info("get result from juejin {}", response);
Map resultMap = JSONObject.parseObject(response, Map.class);
if((Integer) resultMap.get("err_no") != 0){
log.error((String) resultMap.get("err_msg"));
// 推送失败消息
MailRequest mailRequest = new MailRequest();
mailRequest.setText("掘金签到失败!err_msg: " + resultMap.get("err_msg"));
mailRequest.setSendTo(username);
mailRequest.setSubject("juejin sign");
sendMailService.sendMail(mailRequest);
}
}/**
* 抽奖
*/
public void draw(String cookie) throws Exception {
String response = BaseRequest.commonReuqest(DRAW, "POST", cookie);
DrawResponce data= https://www.it610.com/article/JSON.parseObject(response,new TypeReference(){});
log.info(response);
}}
签到请求和抽奖请求都很简单没有参数,带上cookie发一下矿石就到账了,每天第一次抽奖不花矿石,默认第一次抽一下。签到成功就不发邮箱了发多了烦,签到失败会把失败原因发送到配置的邮箱内。
定时任务
@Slf4j
@Component
public class task {@Value("${uptown.cookie}")
String cookie;
@Resource
ActionService actionService;
@Scheduled(cron = "0 0 5 * * ?")
public void run() throws Exception {
log.info("{} start!", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
this.actionService.checkIn(cookie);
// 第一次免费抽奖
this.actionService.draw(cookie);
}
}
最后加上定时任务就完事了,每天5点签到,签到失败发邮箱提醒。用maven打个包放到服务器上
nohup java -jar *.jar &
【java|掘金社区自动签到+免费抽奖】只需要半小时就可以往后只需要通过邮箱提醒处理cookie失效或失败的情况。
推荐阅读
- hashmap|JDK 经典操作 之 HashMap 7、8 之间的差别
- Linux服务器|SpringCloud实用篇02
- 框架|IV XXSC-10
- web|Web全栈~32.深入理解synchronized
- Java从入门到精通(二)|Java中的循环语句
- java|计算平均成绩【JAVA】
- java|阿里面试官(如何测试接口幂等性())
- python|生成对抗网络gans_生成对抗网络gans简介
- SpringBoot|SpringBoot临时属性设置