# `3_Practice_22.py`와 동일한 흐름입니다. # - `resources/lotto_history.txt`(및 크롤 시 `.json`)를 사용합니다. # - 필터만 `final_BallFilter.BallFilter` + `lotto_history.txt` 로딩으로 교체했습니다. # - 회차 번호는 JSON의 `getNo(ymd)` 대신 `lotto_history.txt` 최대 회차 + 1 을 사용합니다. import itertools import json import os import time from datetime import datetime, timedelta import pandas as pd from DataCrawler import DataCrawler from final_BallFilter import BallFilter try: from TelegramBot import TelegramBot except Exception: # pragma: no cover class TelegramBot: def __init__(self, enable=True): pass def sendMsg(self, msg): print(msg) def fetch_lotto_draw_json(drw_no: int): """동행복권 API 한 건. SSL·POST/GET 재시도는 DataCrawler._fetch_draw와 동일.""" return DataCrawler()._fetch_draw(int(drw_no)) class FinalPractice: bot = None def __init__(self, resources_path): self.bot = TelegramBot() def craw(self, lottoHistoryFile, drwNo=None): ball = None if drwNo is not None: result = fetch_lotto_draw_json(drwNo) if result is None: print("경고: 회차 {} API 조회 실패(SSL/네트워크 또는 미추첨).".format(drwNo)) return None jsonFp = open(lottoHistoryFile + ".json", "a", encoding="utf-8") textFp = open(lottoHistoryFile + ".txt", "a", encoding="utf-8") jsonFp.write(json.dumps(result, ensure_ascii=False) + "\n") textFp.write( "%d,%d,%d,%d,%d,%d,%d,%d\n" % ( drwNo, result["drwtNo1"], result["drwtNo2"], result["drwtNo3"], result["drwtNo4"], result["drwtNo5"], result["drwtNo6"], result["bnusNo"], ) ) print( "%d,%d,%d,%d,%d,%d,%d,%d" % ( drwNo, result["drwtNo1"], result["drwtNo2"], result["drwtNo3"], result["drwtNo4"], result["drwtNo5"], result["drwtNo6"], result["bnusNo"], ) ) ball = [ result["drwtNo1"], result["drwtNo2"], result["drwtNo3"], result["drwtNo4"], result["drwtNo5"], result["drwtNo6"], result["bnusNo"], ] jsonFp.close() textFp.close() else: jsonFp = open(lottoHistoryFile + ".json", "w", encoding="utf-8") textFp = open(lottoHistoryFile + ".txt", "w", encoding="utf-8") idx = 1 while True: result = fetch_lotto_draw_json(idx) if result is None or result.get("returnValue") != "success": break jsonFp.write(json.dumps(result, ensure_ascii=False) + "\n") textFp.write( "%d,%d,%d,%d,%d,%d,%d,%d\n" % ( idx, result["drwtNo1"], result["drwtNo2"], result["drwtNo3"], result["drwtNo4"], result["drwtNo5"], result["drwtNo6"], result["bnusNo"], ) ) print( "%d,%d,%d,%d,%d,%d,%d,%d" % ( idx, result["drwtNo1"], result["drwtNo2"], result["drwtNo3"], result["drwtNo4"], result["drwtNo5"], result["drwtNo6"], result["bnusNo"], ) ) ball = [ result["drwtNo1"], result["drwtNo2"], result["drwtNo3"], result["drwtNo4"], result["drwtNo5"], result["drwtNo6"], result["bnusNo"], ] idx += 1 time.sleep(0.5) jsonFp.close() textFp.close() return ball def predict1(self, result_json): result_json.append([6, 7, 10, 11, 20, 45]) def predict2(self, resources_path, ymd, result_json): candidates = [i for i in range(1, 46)] lottoHistoryFileName = os.path.join(resources_path, "lotto_history.txt") df_ball = pd.read_csv(lottoHistoryFileName, header=None) df_ball.columns = ["no", "b1", "b2", "b3", "b4", "b5", "b6", "bn"] no = int(df_ball["no"].max()) + 1 print("회차: {}".format(no)) ballFilter = BallFilter(lottoHistoryFileName) nCr = list(itertools.combinations(candidates, 6)) for idx, ball in enumerate(nCr): if idx % 1000000 == 0: print(" - {} processed...".format(idx)) ball = list(ball) filter_type = ballFilter.filter(ball=ball, no=no, until_end=False, df=df_ball) filter_size = len(filter_type) if 0 < filter_size: continue result_json.append(ball) p_ball = df_ball[df_ball["no"] == no - 1].values.tolist()[0] p_no = p_ball[0] p_ball = p_ball[1:7] return p_no, p_ball if __name__ == "__main__": PROJECT_HOME = "." resources_path = os.path.join(PROJECT_HOME, "resources") dataCrawler = DataCrawler() dataCrawler.excute(resources_path) today = datetime.today() if today.weekday() == 5: if today.hour > 20: this_weekend = today + timedelta(days=(12 - today.weekday())) else: this_weekend = today + timedelta(days=(5 - today.weekday())) elif today.weekday() == 6: this_weekend = today + timedelta(days=(12 - today.weekday())) else: this_weekend = today + timedelta(days=(5 - today.weekday())) last_weekend = (this_weekend - timedelta(days=7)).strftime("%Y%m%d") ymd = this_weekend.strftime("%Y%m%d") print("ymd: {}".format(ymd)) practice = FinalPractice(resources_path) lottoHistoryFile = PROJECT_HOME + "/resources/lotto_history" lottoHistoryFileName = lottoHistoryFile + ".json" with open(lottoHistoryFileName, "r", encoding="utf-8") as f: for line in f: pass last_json = json.loads(line) ball = practice.craw(lottoHistoryFile, drwNo=last_json["drwNo"] + 1) recommend_result_file = os.path.join(resources_path, "recommend_ball.final.json") if os.path.isfile(recommend_result_file): result_fp = open(recommend_result_file, "r", encoding="utf-8") result_json = json.load(result_fp) result_fp.close() result_json[ymd] = [] else: result_json = {ymd: []} practice.predict1(result_json[ymd]) p_no, p_ball = practice.predict2(resources_path, ymd, result_json[ymd]) with open(recommend_result_file, "w", encoding="utf-8") as outFp: json.dump(result_json, outFp, ensure_ascii=False) no_predict = int(p_no) + 1 p_str = "[지난주] {}\n - {} 회차, {}\n[금주] {}\n - {} 회차\n[final_BallFilter]\n".format( last_weekend, p_no, str(p_ball), ymd, no_predict ) for i, ball in enumerate(result_json[ymd]): p_str += " {}. {}\n".format((i + 1), str(ball)) if (i + 1) % 100 == 0: practice.bot.sendMsg("{}".format(p_str)) p_str = "" if len(result_json[ymd]) % 100 != 0: practice.bot.sendMsg("{}".format(p_str)) size = len(result_json[ymd]) print("size: {}".format(size)) print("done...")