From 410435720e08a31dc6a966ded267c0e90cedb740 Mon Sep 17 00:00:00 2001 From: fengche <1158629543@qq.com> Date: Mon, 15 Dec 2025 17:39:35 +0800 Subject: [PATCH] =?UTF-8?q?2miners=E7=9F=BF=E6=B1=A0=E7=AE=97=E5=8A=9B?= =?UTF-8?q?=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- v1/miner_2miners_collector.py | 108 ++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 v1/miner_2miners_collector.py diff --git a/v1/miner_2miners_collector.py b/v1/miner_2miners_collector.py new file mode 100644 index 0000000..ef3bed2 --- /dev/null +++ b/v1/miner_2miners_collector.py @@ -0,0 +1,108 @@ +import redis +import requests +import pymysql +from datetime import datetime, timedelta +import time + +# ---------------- Redis 配置 ---------------- +r = redis.Redis(host='127.0.0.1', port=6379, db=7, decode_responses=True) + +# ---------------- MySQL 配置 ---------------- +conn = pymysql.connect( + host='127.0.0.1', + user='root', + password='123456', + database='pool', + port=25600, + charset='utf8mb4' +) +cursor = conn.cursor() + +# ---------------- API 配置 ---------------- +API_URLS = { + "NEXA": "https://nexa.2miners.com/api/accounts/{wallet}", + "XNA": "https://xna.2miners.com/api/accounts/{wallet}", + "CLORE": "https://clore.2miners.com/api/accounts/{wallet}", + "RVN": "https://rvn.2miners.com/api/accounts/{wallet}", + "ERG": "https://erg.2miners.com/api/accounts/{wallet}" +} + +# ---------------- 工具函数 ---------------- +def to_mhs(value): + """算力转换为 MH/s""" + return float(value) / 1_000_000 if value else 0.0 + +def get_half_hour_time(now): + """取最近半点时间""" + minute = 0 if now.minute < 30 else 30 + return now.replace(minute=minute, second=0, microsecond=0) + +# ---------------- 主逻辑 ---------------- +def query_and_insert(): + keys = r.keys("*") # 遍历所有 key + half_hour_time = get_half_hour_time(datetime.now()) + + for key in keys: + try: + # key 格式: pool_name:wallet:coin:algo + parts = key.split(":") + if len(parts) != 4: + continue + pool_name, wallet, coin, algo = parts + if pool_name.lower() != "2miners": + continue # 不是 2Miners 的数据就跳过 + coin_upper = coin.upper() + + if coin_upper not in API_URLS: + print(f"币种 {coin_upper} 不在支持列表中,跳过") + continue + + # NEXA 特殊处理,其他币种直接用 wallet + if coin_upper == "NEXA" and not wallet.lower().startswith("nexa:"): + wallet_for_api = f"nexa:{wallet}" + else: + wallet_for_api = wallet + + url = API_URLS[coin_upper].format(wallet=wallet_for_api) + resp = requests.get(url, timeout=10) + resp.raise_for_status() + data = resp.json() + + # 遍历矿机 + workers = data.get("workers", {}) + if not workers: + print(f"{coin_upper} 钱包 {wallet} 没有矿机数据") + continue + + for miner_name, miner_data in workers.items(): + hashrate = to_mhs(miner_data.get("hr")) + print(f"池:{pool_name} 币种:{coin_upper} 钱包:{wallet} 矿机:{miner_name} -> {hashrate:.2f} MH/s") + + # 写入数据库 + sql = """ + INSERT INTO `2miners` + (datetime, pool_name, wallet, miner, hashrate, coin, algorithm) + VALUES (%s,%s,%s,%s,%s,%s,%s) + """ + cursor.execute(sql, (half_hour_time, pool_name, wallet, miner_name, hashrate, coin_upper, algo)) + conn.commit() + + except Exception as e: + print("请求或解析失败:", e) + +# ---------------- 定时执行 ---------------- +if __name__ == "__main__": + try: + while True: + now = datetime.now() + next_minute = 30 if now.minute < 30 else 60 + wait_seconds = (next_minute - now.minute) * 60 - now.second + if wait_seconds > 0: + print(f"等待 {wait_seconds} 秒到下一个半点...") + time.sleep(wait_seconds) + query_and_insert() + except KeyboardInterrupt: + print("程序结束") + finally: + cursor.close() + conn.close() \ No newline at end of file