登入失败禁止登入2

This commit is contained in:
xuelijun
2026-01-31 17:44:04 +08:00
parent 4c2fe1d2a1
commit f852676c83
5 changed files with 287 additions and 11 deletions

BIN
bocai.db

Binary file not shown.

View File

@@ -5,9 +5,13 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
@Repository
public interface LotteryResultRepository extends JpaRepository<LotteryResult, Long> {
// 根据时间查询使用like匹配日期部分
List<LotteryResult> findByTimeContaining(String date);
// 查询最新的记录按time降序取第一条
Optional<LotteryResult> findTopByOrderByTimeDesc();
}

View File

@@ -1,7 +1,9 @@
package com.tem.bocai.schedules;
import com.tem.bocai.entity.LoginInfoResult;
import com.tem.bocai.entity.LotteryResult;
import com.tem.bocai.repository.LoginInfoRepository;
import com.tem.bocai.repository.LotteryResultRepository;
import com.tem.bocai.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
@@ -11,10 +13,12 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Spider;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
@Slf4j
@@ -24,6 +28,10 @@ public class CrawlerSchedule {
private TokenCacheService tokenCacheService;
@Autowired
private LoginInfoRepository loginInfoRepository;
@Autowired
private LotteryResultRepository lotteryResultRepository;
private static final int MAX_CRA = 3;
private static final Integer ONOFF = 0;
@Value("${pypath}")
@@ -31,11 +39,11 @@ public class CrawlerSchedule {
// 每天凌晨2点执行爬取开奖结果
//@Scheduled(cron = "0 0 2 * * ?")
// 每7秒执行一次爬取开奖结果
//@Scheduled(cron = "*/9 * * * * ?")
@Scheduled(cron = "*/9 * * * * ?")
/*@Scheduled(cron = "0 6-59/5 7-23 * * ?")
@Scheduled(cron = "0 0-55/5 0-6 * * ?")*/
// 从7:00分30秒起每5分钟执行一次
@Scheduled(cron = "30 0/5 * * * ?")
//@Scheduled(cron = "30 0/5 * * * ?")
public void executeLotteryDraw() {
log.info("开始爬取开奖结果");
int retryCount = 0;
@@ -45,10 +53,13 @@ public class CrawlerSchedule {
if (firstByOrderByCreateTimeDesc == null) {
return;
}
if(firstByOrderByCreateTimeDesc.getOnOff() == ONOFF){
return;
}
String token = tokenCacheService.getToken();
if (token == null || token.isEmpty()) {
return;
}
if (token == null || token.isEmpty()) {
return;
}
while (!success && retryCount < MAX_CRA) {
log.info("\n=== 第 " + (retryCount + 1) + " 次尝试获取开奖结果 ===");
if (token == null || token.isEmpty()) {
@@ -99,6 +110,31 @@ public class CrawlerSchedule {
}
//@Scheduled(cron = "50 0/5 * * * ?")
public void executePksHistory() {
log.info("开始获取历史开奖结果");
// 获取API数据
List<Map<String, Object>> historyList = HttpClientExample.getPksHistoryList();
// 获取数据库最新时间
Optional<String> latestTimeOpt = lotteryResultRepository.findTopByOrderByTimeDesc()
.map(LotteryResult::getTime);
// 判断是否需要更新
boolean needUpdate = latestTimeOpt
.map(latestTime -> historyList.stream()
.noneMatch(item -> latestTime.equals(item.get("time"))))
.orElse(true); // 数据库为空时需要更新
if (needUpdate) {
log.info("需要更新数据,最新时间:{}",
latestTimeOpt.orElse("数据库为空"));
HttpClientExample.getPksHistory(historyList, pypath);
} else {
log.info("数据已是最新,无需更新");
}
}
/*public void executeLotteryDraw() {
System.out.println("开始爬取开奖结果...");
String token = tokenCacheService.getToken();
@@ -119,7 +155,7 @@ public class CrawlerSchedule {
// 从7:00分30秒起每5分钟执行一次爬取今日已经结算
@Scheduled(cron = "35 0/5 * * * ?")
//@Scheduled(cron = "35 0/5 * * * ?")
public void executeSettlement() {
log.info("开始爬取今日已经结算...");
int retryCount = 0;
@@ -128,6 +164,11 @@ public class CrawlerSchedule {
if (token == null || token.isEmpty()) {
return;
}
LoginInfoResult firstByOrderByCreateTimeDesc = loginInfoRepository.findFirstByOrderByCreateTimeDesc()
.orElse(null);
if(firstByOrderByCreateTimeDesc.getOnOff() == ONOFF){
return;
}
while (!success && retryCount < MAX_CRA) {
log.info("\n=== 第 " + (retryCount + 1) + " 次尝试获取今日注单 ===");
if (token == null || token.isEmpty()) {
@@ -141,8 +182,7 @@ public class CrawlerSchedule {
// 创建爬虫实例传入token
CompletedTodayCrawler crawler = new CompletedTodayCrawler(token);
LoginInfoResult firstByOrderByCreateTimeDesc = loginInfoRepository.findFirstByOrderByCreateTimeDesc()
.orElse(null);
// 执行爬虫
String url = firstByOrderByCreateTimeDesc.getLoginUrl()+"/member/bets?settled=true";
@@ -195,6 +235,6 @@ public class CrawlerSchedule {
.run();
}
}*/
}

View File

@@ -0,0 +1,232 @@
package com.tem.bocai.util;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.ssl.SSLContexts;
import org.apache.hc.core5.ssl.TrustStrategy;
import org.apache.hc.core5.util.Timeout;
import org.springframework.beans.factory.annotation.Value;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
public class HttpClientExample {
public static String getPksHistory(List<Map<String, Object>> resultList ,String pypath) {
// 将数据写入SQLite数据库
SQLiteUtil.writeToSQLite(resultList);
// 将数据写入JSON文件保留原有功能
writeToJsonFile(resultList,pypath);
log.info("历史爬虫打印结果===" + resultList);
return "";
}
public static List<Map<String, Object>> getPksHistoryList(){
List<Map<String, Object>> resultList = new ArrayList<>();
String todayDate = DateUtils.getTodayDate();
try {
String url = "https://api.api168168.com/pks/getPksHistoryList.do?lotCode=10058&"+todayDate;
// 设置代理 127.0.0.1:7890
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(proxy);
conn.setRequestMethod("GET");
conn.setRequestProperty("Origin", "https://xy678kjw.com");
conn.setRequestProperty("Referer", "https://xy678kjw.com/");
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36");
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
// 使用Jackson解析JSON
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(response.toString());
// 检查是否成功
int errorCode = rootNode.get("errorCode").asInt();
if (errorCode == 0) {
// 获取data数组
JsonNode dataArray = rootNode
.get("result")
.get("data");
if (dataArray.isArray()) {
for (JsonNode item : dataArray) {
Map<String, Object> map = new HashMap<>();
// 解析原始数据
String preDrawCode = item.get("preDrawCode").asText();
String[] codeArray = preDrawCode.split(",");
// 转换为整数数组
int[] result = new int[codeArray.length];
for (int i = 0; i < codeArray.length; i++) {
result[i] = Integer.parseInt(codeArray[i].trim());
}
// 计算sum1和sum2
int sum1 = 0;
int sum2 = 0;
for (int i = 0; i < 5; i++) {
sum1 += result[i];
}
for (int i = 5; i < 10; i++) {
sum2 += result[i];
}
// 计算winner前五个号码的和
int winner = sum1;
// 计算冠亚和(前两个号码的和)
int championSum = result[0] + result[1];
// 判断冠亚单双
String GD2 = (championSum % 2 == 0) ? "冠亚双" : "冠亚单";
// 判断冠亚大小冠亚和11为大11为小
String GD1 = (championSum > 11) ? "冠亚大" : "冠亚小";
if (championSum == 11) {
GD1 = "冠亚小"; // 特殊处理和值为11算小
}
// 计算龙虎1-5位对比
List<String> GLH_result = new ArrayList<>();
for (int i = 0; i < 5; i++) {
if (result[i] > result[9 - i]) {
GLH_result.add("");
} else {
GLH_result.add("");
}
}
// 构建转换后的map
map.put("result", result);
map.put("sum1", sum1);
map.put("sum2", sum2);
map.put("winner", winner);
map.put("GD2", GD2);
map.put("GD1", GD1);
map.put("GLH_result", GLH_result);
map.put("id", String.valueOf(item.get("preDrawIssue").asLong()));
map.put("time", item.get("preDrawTime").asText());
resultList.add(map);
}
}
}
// 打印转换后的结果列表
System.out.println("Total records: " + resultList.size());
// 使用ObjectMapper将结果列表转换为JSON格式输出
ObjectMapper outputMapper = new ObjectMapper();
String jsonOutput = outputMapper.writerWithDefaultPrettyPrinter().writeValueAsString(resultList);
System.out.println(jsonOutput);
// 或者以自定义格式输出(可选)
System.out.println("\n=== 转换后的数据格式 ===");
for (Map<String, Object> map : resultList) {
System.out.println("{");
System.out.println(" \"result\" : " + Arrays.toString((int[]) map.get("result")) + ",");
System.out.println(" \"sum1\" : " + map.get("sum1") + ",");
System.out.println(" \"sum2\" : " + map.get("sum2") + ",");
System.out.println(" \"winner\" : " + map.get("winner") + ",");
System.out.println(" \"GD2\" : \"" + map.get("GD2") + "\",");
System.out.println(" \"GD1\" : \"" + map.get("GD1") + "\",");
System.out.println(" \"GLH_result\" : " + map.get("GLH_result") + ",");
System.out.println(" \"id\" : \"" + map.get("id") + "\",");
System.out.println(" \"time\" : \"" + map.get("time") + "\"");
System.out.println("},");
}
} catch (Exception e) {
e.printStackTrace();
}
return resultList;
}
public static void writeToJsonFile(List<Map<String, Object>> resultList,String pypath) {
try {
// 创建 ObjectMapper 实例
ObjectMapper objectMapper = new ObjectMapper();
// 设置 JSON 格式化(可选,更易读)
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// 定义输出目录
String directoryPath = pypath+"/current_data"; // 项目根目录下的 output/json 文件夹
// 使用年月日作为文件名格式result_yyyyMMdd.json
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = dateFormat.format(new Date());
String fileName = "result_" + dateStr + ".json";
String filePath = directoryPath + "/" + fileName;
// 创建目录(如果不存在)
File directory = new File(directoryPath);
if (!directory.exists()) {
directory.mkdirs(); // 创建多级目录
}
// 创建文件对象
File outputFile = new File(filePath);
// 如果文件已存在,删除旧文件(实现替换功能)
if (outputFile.exists()) {
boolean deleted = outputFile.delete();
if (!deleted) {
throw new IOException("无法删除已存在的文件: " + filePath);
}
System.out.println("已删除旧文件,准备创建新文件: " + fileName);
}
// 将 List 写入 JSON 文件
objectMapper.writeValue(outputFile, resultList);
log.info("数据已成功写入文件: " + outputFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
log.error("写入 JSON 文件失败: " + e.getMessage(), e);
throw new RuntimeException("写入 JSON 文件失败: " + e.getMessage(), e);
}
}
}

View File

@@ -10,4 +10,4 @@ spring.jpa.show-sql=true
spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
pypath:d:/py/PyModel
pypath:c:/py/PyModel