|
|
@@ -5,7 +5,6 @@ import com.alibaba.fastjson2.JSON;
|
|
|
import com.jzg.commons.exception.SystemException;
|
|
|
import com.jzg.quotation.commons.component.RequestComponent;
|
|
|
import com.jzg.quotation.commons.constant.CacheConstant;
|
|
|
-import com.jzg.quotation.commons.constant.enums.CaptchaIdentifyType;
|
|
|
import com.jzg.quotation.commons.service.ExteriorUtilsRequest;
|
|
|
import com.jzg.quotation.commons.standard.CrawlerRequestUrlStandard;
|
|
|
import com.jzg.quotation.dajia.crawler.constant.enums.RequestUrl;
|
|
|
@@ -14,7 +13,6 @@ import com.jzg.quotation.dajia.crawler.entity.response.*;
|
|
|
import com.jzg.quotation.dajia.crawler.utils.DESEncryption;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.redisson.api.RBucket;
|
|
|
import org.redisson.api.RedissonClient;
|
|
|
import org.springframework.http.HttpHeaders;
|
|
|
import org.springframework.http.HttpStatus;
|
|
|
@@ -40,31 +38,80 @@ public class DaJiaRequestComponent {
|
|
|
|
|
|
private final ExteriorUtilsRequest exteriorUtilsRequest;
|
|
|
|
|
|
+ // 循环次数
|
|
|
+ public static final int CIRCULATE_NUMBER = 3;
|
|
|
+ // 登陆次数
|
|
|
+ public static final int LOGINS_NUMBER = 3;
|
|
|
+
|
|
|
+ public int processCaptcha(String res) {
|
|
|
+ // 检查字符串长度是否足够,并且第三个字符不是'='
|
|
|
+ if (res.length() >= 3 && res.charAt(2) != '=') {
|
|
|
+ char operator = res.charAt(1);
|
|
|
+ try {
|
|
|
+ int operand1 = Integer.parseInt(res.substring(0, 1));
|
|
|
+ int operand2 = Integer.parseInt(res.substring(2, 3));
|
|
|
+ // 注意:这里假设操作符和操作数都是有效的,实际应用中应该添加更多的错误处理
|
|
|
+
|
|
|
+ switch (operator) {
|
|
|
+ case '+':
|
|
|
+ case 'f': // 通常'f'不是加法运算符,但根据原代码保留
|
|
|
+ return operand1 + operand2;
|
|
|
+ case 'x':
|
|
|
+ case 'X':
|
|
|
+ case '4': // 通常'4'不是乘法运算符,但保留以匹配原代码
|
|
|
+ case '9': // 通常'9'也不是乘法运算符,但保留以匹配原代码
|
|
|
+ return operand1 * operand2;
|
|
|
+ case '-':
|
|
|
+ case 'e': // 通常'e'不是减法运算符,但根据原代码保留
|
|
|
+ case '=': // 通常'='不是减法运算符,但根据原代码保留
|
|
|
+ case '2': // 通常'2'也不是减法运算符,但根据原代码保留
|
|
|
+ return operand1 - operand2;
|
|
|
+ // 如果操作符不匹配,则获取新的验证码图片(模拟)
|
|
|
+ }
|
|
|
+ } catch (NumberFormatException ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ throw new SystemException("");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 验证码
|
|
|
*
|
|
|
* @return
|
|
|
*/
|
|
|
- public DaJiaCrawlerCaptchaResponse captcha() {
|
|
|
+ public DaJiaCrawlerCaptchaResponse captcha(int frequency) {
|
|
|
+ if (frequency <= 0) {
|
|
|
+ throw new SystemException("验证码异常");
|
|
|
+ }
|
|
|
Map<String, Object> map = Map.of("imgId", UUID.randomUUID().toString().replaceAll("-", ""));
|
|
|
// 请求
|
|
|
DaJiaCrawlerBaseResponse request = requestComponent.requestGET(RequestUrl.BASE_URL, RequestUrl.CAPTCHA, map, DaJiaCrawlerBaseResponse.class);
|
|
|
String decrypt = DESEncryption.decrypt(request.getResult());
|
|
|
- return JSON.parseObject(decrypt, DaJiaCrawlerCaptchaResponse.class);
|
|
|
+ DaJiaCrawlerCaptchaResponse daJiaCrawlerCaptchaResponse = JSON.parseObject(decrypt, DaJiaCrawlerCaptchaResponse.class);
|
|
|
+ // 识别验证码
|
|
|
+ String s = exteriorUtilsRequest.captchaIdentify(daJiaCrawlerCaptchaResponse.getImg());
|
|
|
+ try {
|
|
|
+ int i = processCaptcha(s);
|
|
|
+ s = String.valueOf(i);
|
|
|
+ } catch (Exception e) {
|
|
|
+ frequency = frequency - 1;
|
|
|
+ return captcha(frequency);
|
|
|
+ }
|
|
|
+ daJiaCrawlerCaptchaResponse.setImg(s);
|
|
|
+ return daJiaCrawlerCaptchaResponse;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 登录
|
|
|
+ * 登录次数
|
|
|
*
|
|
|
- * @param request 登录请求体
|
|
|
+ * @param username 用户名
|
|
|
+ * @param password 密码
|
|
|
+ * @param loginsNumber 登录次数
|
|
|
* @return token
|
|
|
*/
|
|
|
- public String authenticate(String username, String password) {
|
|
|
+ public String authenticate(String username, String password, int loginsNumber) {
|
|
|
// 登录验证码获取
|
|
|
- DaJiaCrawlerCaptchaResponse captcha = captcha();
|
|
|
- // 识别验证码
|
|
|
- String s = exteriorUtilsRequest.captchaIdentify(captcha.getImg(), CaptchaIdentifyType.TYPE_1);
|
|
|
- captcha.setImg(s);
|
|
|
+ DaJiaCrawlerCaptchaResponse captcha = captcha(CIRCULATE_NUMBER);
|
|
|
// 登录存入缓存当中
|
|
|
DaJiaCrawlerAuthenticateRequest request = new DaJiaCrawlerAuthenticateRequest(captcha, username, password);
|
|
|
ResponseEntity<DaJiaCrawlerBaseResponse> responseEntity = requestComponent.objectPost(RequestUrl.BASE_URL, RequestUrl.AUTHENTICATE, request, DaJiaCrawlerBaseResponse.class);
|
|
|
@@ -72,23 +119,29 @@ public class DaJiaRequestComponent {
|
|
|
String authorization = responseEntity.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);
|
|
|
// 判断请求是否成功和授权码是否返回
|
|
|
if (HttpStatus.OK.value() != statusCode.value() && !StringUtils.hasLength(authorization)) {
|
|
|
- String message = Optional.ofNullable(responseEntity.getBody())
|
|
|
- .map(DaJiaCrawlerBaseResponse::getMessage)
|
|
|
- .orElseThrow(() -> new SystemException("登录失败"));
|
|
|
- throw new SystemException(message);
|
|
|
+ loginsNumber = loginsNumber - 1;
|
|
|
+ if (loginsNumber <= 0) {
|
|
|
+ String message = Optional.ofNullable(responseEntity.getBody())
|
|
|
+ .map(DaJiaCrawlerBaseResponse::getMessage)
|
|
|
+ .orElseThrow(() -> new SystemException("登录失败"));
|
|
|
+ throw new SystemException(message);
|
|
|
+ }
|
|
|
+ return authenticate(username, password, loginsNumber);
|
|
|
}
|
|
|
redissonClient.getBucket(CacheConstant.DAJIA_AUTHORIZATION + username).set(authorization, Duration.ofHours(CacheConstant.DAJIA_AUTHORIZATION_TIME));
|
|
|
return authorization;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 获取请求头
|
|
|
+ *
|
|
|
* @return
|
|
|
*/
|
|
|
- public HttpHeaders getHeaders(String username, String password){
|
|
|
+ public HttpHeaders getHeaders(String username, String password) {
|
|
|
String authorization = (String) redissonClient.getBucket(CacheConstant.DAJIA_AUTHORIZATION).get();
|
|
|
- if(!StringUtils.hasLength(authorization)){
|
|
|
- authorization = authenticate(username, password);
|
|
|
+ if (!StringUtils.hasLength(authorization)) {
|
|
|
+ authorization = authenticate(username, password, LOGINS_NUMBER);
|
|
|
}
|
|
|
HttpHeaders headers = new HttpHeaders();
|
|
|
headers.set(HttpHeaders.AUTHORIZATION + password, authorization);
|
|
|
@@ -104,18 +157,19 @@ public class DaJiaRequestComponent {
|
|
|
public <DaJiaResponse> DaJiaResponse request(CrawlerRequestUrlStandard crawlerRequestUrlStandard, Object request, Class<DaJiaResponse> responseClass, HttpHeaders headers) {
|
|
|
ResponseEntity<DaJiaCrawlerBaseResponse> responseEntity = requestComponent.objectPost(crawlerRequestUrlStandard, request, DaJiaCrawlerBaseResponse.class, headers);
|
|
|
DaJiaCrawlerBaseResponse daJiaCrawlerBaseResponse = responseEntity.getBody();
|
|
|
-
|
|
|
String decrypt = DESEncryption.decrypt(daJiaCrawlerBaseResponse.getResult());
|
|
|
return JSON.parseObject(decrypt, responseClass);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 车型查询
|
|
|
+ *
|
|
|
* @param daJiaCrawlerCarRequest 车型查询请求体
|
|
|
- * @param headers 请求头
|
|
|
+ * @param headers 请求头
|
|
|
* @return 车型列表
|
|
|
*/
|
|
|
- public List<DaJiaCrawlerCarResponse.ListDTO> car(DaJiaCrawlerCarRequest daJiaCrawlerCarRequest, HttpHeaders headers){
|
|
|
+ public List<DaJiaCrawlerCarResponse.ListDTO> car(DaJiaCrawlerCarRequest daJiaCrawlerCarRequest, HttpHeaders
|
|
|
+ headers) {
|
|
|
DaJiaCrawlerCarResponse request = request(RequestUrl.CAR, daJiaCrawlerCarRequest, DaJiaCrawlerCarResponse.class, headers);
|
|
|
return request.getList();
|
|
|
}
|
|
|
@@ -156,5 +210,4 @@ public class DaJiaRequestComponent {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
}
|