import os import tempfile import requests import pandas as pd import gradio as gr import spaces from bs4 import BeautifulSoup from datasets import Dataset from huggingface_hub import HfApi # =========================== # CONFIG # =========================== URL_DEFAULT = "https://www.ketquadientoan.com/tra-cuu-ket-qua-xo-so-dien-toan-power-655.html?" DATASET_REPO = "Mrlongpro/power655-dataset" CSV_NAME = "history.csv" HF_TOKEN = os.getenv("HF_TOKEN") HEADERS = { "User-Agent": "Mozilla/5.0" } api = HfApi(token=HF_TOKEN) # =========================== # FEATURE ENGINEERING # =========================== def create_features(df): vectors = [] for _, row in df.iterrows(): vec = [0] * 55 nums = [ int(row["S1"]), int(row["S2"]), int(row["S3"]), int(row["S4"]), int(row["S5"]), int(row["S6"]), ] for n in nums: vec[n - 1] = 1 feature = { "Sum": sum(nums), "Mean": sum(nums) / 6, "Odd": sum(x % 2 for x in nums), "Even": 6 - sum(x % 2 for x in nums), "Min": min(nums), "Max": max(nums), } for i in range(55): feature[f"N{i+1:02}"] = vec[i] vectors.append(feature) feature_df = pd.DataFrame(vectors) return pd.concat( [df.reset_index(drop=True), feature_df], axis=1, ) # =========================== # LOAD DATASET # =========================== def load_history(): try: api.hf_hub_download( repo_id=DATASET_REPO, repo_type="dataset", filename=CSV_NAME, local_dir="." ) return pd.read_csv(CSV_NAME) except: return pd.DataFrame() # =========================== # SAVE DATASET # =========================== def save_dataset(df): df.to_csv( CSV_NAME, index=False, encoding="utf-8-sig" ) api.upload_file( path_or_fileobj=CSV_NAME, path_in_repo=CSV_NAME, repo_id=DATASET_REPO, repo_type="dataset", commit_message="Update Power655" ) Dataset.from_pandas(df).push_to_hub( DATASET_REPO, token=HF_TOKEN ) # =========================== # CRAWLER # =========================== @spaces.GPU def crawl(url): try: r = requests.get( url, headers=HEADERS, timeout=30, ) r.raise_for_status() soup = BeautifulSoup( r.text, "html.parser", ) options = soup.select( "select.dongay option" ) data = [] for op in options: if op.get("value") == "0": continue nums = op["value"].split(",") data.append({ "Ngày": op.text.strip(), "S1": int(nums[0]), "S2": int(nums[1]), "S3": int(nums[2]), "S4": int(nums[3]), "S5": int(nums[4]), "S6": int(nums[5]), "Số phụ": int(op["jphu"]), "Jackpot1": int(op["price"]), "Jackpot2": int(op["price2"]) }) df = pd.DataFrame(data) df = create_features(df) old = load_history() if len(old): df = pd.concat( [old, df], ignore_index=True ) df = df.drop_duplicates( subset=["Ngày"], keep="first" ) save_dataset(df) outfile = os.path.join( tempfile.gettempdir(), "power655.csv" ) df.to_csv( outfile, index=False, encoding="utf-8-sig" ) return ( df, outfile, f"Đã cập nhật {len(df)} kỳ quay." ) except Exception as e: return ( pd.DataFrame(), None, str(e) ) # =========================== # UI # =========================== with gr.Blocks() as demo: gr.Markdown( "# 🎯 Power 6/55 Dataset Builder" ) url = gr.Textbox( value=URL_DEFAULT, label="URL" ) btn = gr.Button( "Cập nhật Dataset" ) status = gr.Textbox( label="Trạng thái" ) table = gr.Dataframe( interactive=False ) file = gr.File() btn.click( crawl, inputs=url, outputs=[ table, file, status ] ) demo.launch()