lottery_4frame + cron-prompts: 字段语义残余清理

修:
- lottery_4frame.py line 52 docstring: Qi=下次将开 → Qi=最新已开
- lottery_4frame.py line 153 step 1 header: Qi 下期开彩 → Qi 最新已开
- lottery_4frame.py line 162: Qi 期开彩(从 Nq 推算) → 清晰说 Nq 期
- lottery_4frame.py main(): 默认 082 → 自动取 v_xg.json Qi
- lottery_4frame.py line 2 doc: 写死 '082 期' → 动态 Qi
- cron-prompts/lottery-hot-data.md: Qi=下次将开 → 最新已开
- cron-prompts/lottery-draw-result.md: 同上

输出验证 (8/4 跑):
  083 期 4 框架玄学分析 (按 lottery-hk skill v1.2.7 流程)
  Qi (最新已开) = 083, Nq (未开下期) = 084
  Data.1-7 = Qi-2 期 81 已开号码 (不是 Qi-1!)
  Qi 期开彩日(从 Nq 推算): Nq 期开彩日 Week=周二 Day=04 - 3 天
This commit is contained in:
2026-08-04 15:56:52 +08:00
parent 1ce16515e1
commit a2bc7b18e3
3 changed files with 110 additions and 50 deletions
@@ -4,10 +4,10 @@
1. **时区**: 所有时间默认北京时间 (UTC+8) 1. **时区**: 所有时间默认北京时间 (UTC+8)
2. **挂牌日 = 开彩日** (sol.2344a.cc 帖子时间戳 = 实际开奖日, 同天) 2. **挂牌日 = 开彩日** (sol.2344a.cc 帖子时间戳 = 实际开奖日, 同天)
3. **v_xg.json 字段 (2026-08-02 修正)**: 3. **v_xg.json 字段 (2026-08-02 修正)**:
- Qi = 下次将开期号 - Qi = 最新已开期号 (刚开)
- Nq = 再下期 - Nq = 再下期
- Data.1-7 = **Qi-2 期已开号码** (不是 Qi-1) - Data.1-7 = **Qi-2 期已开号码** (不是 Qi-1)
- Week/Day/Year/Moon = Qi 期开彩日 (北京时间) - Week/Day/Year/Moon = Nq 期开彩日 (北京时间)
⚠️ cron 模式 terminal/execute_code 被拦,必须用真脚本。 ⚠️ cron 模式 terminal/execute_code 被拦,必须用真脚本。
+2 -2
View File
@@ -4,10 +4,10 @@
1. **时区**: 所有时间默认北京时间 (UTC+8) 1. **时区**: 所有时间默认北京时间 (UTC+8)
2. **挂牌日 = 开彩日** (sol.2344a.cc 帖子时间戳 = 实际开奖日, 同天) 2. **挂牌日 = 开彩日** (sol.2344a.cc 帖子时间戳 = 实际开奖日, 同天)
3. **v_xg.json 字段 (2026-08-02 修正)**: 3. **v_xg.json 字段 (2026-08-02 修正)**:
- Qi = 下次将开期号 - Qi = 最新已开期号 (刚开)
- Nq = 再下期 - Nq = 再下期
- Data.1-7 = **Qi-2 期已开号码** (不是 Qi-1) - Data.1-7 = **Qi-2 期已开号码** (不是 Qi-1)
- Week/Day/Year/Moon = Qi 期开彩日 (北京时间) - Week/Day/Year/Moon = Nq 期开彩日 (北京时间)
⚠️ cron 模式 terminal/execute_code 被拦,必须用真脚本。 ⚠️ cron 模式 terminal/execute_code 被拦,必须用真脚本。
+106 -46
View File
@@ -1,6 +1,9 @@
""" """
082 期 4 框架玄学分析 — 真实脚本 (替代 model 手动推演) # lottery 4 框架玄学分析 — 真实脚本 (替代 model 手动推演, 动态取 Qi)
基于 references/analysis-example-073/074/075.md 的 3 步推演流程 基于 references/analysis-example-073/074/075.md 的 3 步推演流程
【2026-08-02 修复】sol.2344a.cc 出现 "Cann't connect to DB!" 时静默失败
→ 加 fail-fast 错误检测 (check_db_error)
""" """
import os import os
import sys import sys
@@ -16,32 +19,77 @@ TIMEZONE_BEIJING = "北京时间 (UTC+8)"
SOL_BASE = "https://sol.2344a.cc" SOL_BASE = "https://sol.2344a.cc"
V_XG_URL = "https://btc.tktk.app/data/v_xg.json" V_XG_URL = "https://btc.tktk.app/data/v_xg.json"
# === 错误检测 pattern (2026-08-02 实战发现) ===
DB_ERROR_PATTERNS = [
"Cann't connect to DB!",
"Can't connect to DB!",
"database connection failed",
"internal server error",
"数据库连接失败",
]
def check_db_error(data, source_name):
"""检测 sol.2344a.cc / tktk 临时 DB 错误 → fail-fast"""
if not isinstance(data, str):
return data # 非字符串, 可能是 JSON
for pattern in DB_ERROR_PATTERNS:
if pattern.lower() in data.lower():
raise RuntimeError(
f"[{source_name}] DB 错误: {data[:200]!r}\n"
f" 触发 pattern: {pattern!r}\n"
f" 修复: 等 sol.2344a.cc 恢复, 或用本地 SQLite draws 表作为 fallback"
)
if "页面使用Vue.js动态加载" in data:
raise RuntimeError(
f"[{source_name}] Vue.js 动态加载 (cron 模式拿不到数据), "
f"改用 browser_snapshot(full=true) 或 fallback 方案"
)
return data
def fetch_v_xg(): def fetch_v_xg():
"""拉 v_xg.json (Qi=下次将开, Data.1-7=Qi-2 已开 (不是 Qi-1))""" """拉 v_xg.json (Qi=最新已开, Data.1-7=Qi-2 已开 (不是 Qi-1))"""
try: try:
req = urllib.request.Request(V_XG_URL, headers={'User-Agent': 'Mozilla/5.0'}) req = urllib.request.Request(V_XG_URL, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=15) as r: with urllib.request.urlopen(req, timeout=15) as r:
return json.loads(r.read().decode('utf-8')) data = json.loads(r.read().decode('utf-8'))
# 检查 Qi 字段 (防止 DB 错误 JSON)
if 'Qi' not in data or data.get('Qi') == '?':
raise RuntimeError(f"v_xg.json 缺 Qi 字段: {data!r}")
return data
except RuntimeError:
raise
except Exception as e: except Exception as e:
return {'Data': {}, 'Qi': '?', 'Nq': '?', 'Week': '?', 'Day': '?', 'error': str(e)} raise RuntimeError(f"v_xg.json 网络错误: {e}") from e
def curl_url(url): def curl_url(url):
"""curl via mihomo proxy, return raw text""" """curl via mihomo proxy, return raw text
[2026-08-02 修复] 加 DB 错误检测 → fail-fast
"""
import subprocess import subprocess
try: try:
result = subprocess.run( result = subprocess.run(
['curl', '-x', 'http://127.0.0.1:7890', '-L', '-s', url], ['curl', '-x', 'http://127.0.0.1:7890', '-L', '-s', url],
capture_output=True, text=True, timeout=20 capture_output=True, text=True, timeout=20
) )
if result.returncode != 0:
raise RuntimeError(f"curl {url} returncode={result.returncode}: {result.stderr[:200]}")
# fail-fast: 检测 DB 错误
check_db_error(result.stdout, f"curl {url}")
return result.stdout return result.stdout
except RuntimeError:
raise
except Exception as e: except Exception as e:
return f"[error: {e}]" raise RuntimeError(f"curl {url} 异常: {e}") from e
def fetch_sol_list(path, marker, limit=5): def fetch_sol_list(path, marker, limit=5):
"""拉 sol.2344a.cc 列表页, 摘 marker (期号) 行""" """拉 sol.2344a.cc 列表页, 摘 marker (期号) 行
[2026-08-02 修复] marker 写死 "082" 是 bug, 改用 period 参数
"""
html = curl_url(f'{SOL_BASE}{path}') html = curl_url(f'{SOL_BASE}{path}')
lines = [] lines = []
for line in html.split('\n'): for line in html.split('\n'):
@@ -49,10 +97,8 @@ def fetch_sol_list(path, marker, limit=5):
# 去 HTML tag # 去 HTML tag
import re import re
clean = re.sub(r'<[^>]+>', ' ', line).strip() clean = re.sub(r'<[^>]+>', ' ', line).strip()
# 提取 082期:... 直到 " # 提取 marker 期号:... 直到 "
m = re.search(r'082[^"]*?(?=</)', clean) m = re.search(rf'{re.escape(marker)}[^\"]*?(?=</)', clean) or re.search(rf'{re.escape(marker)}[^\"]*', clean)
if not m:
m = re.search(r'082[^"]*', clean)
if m and m.group(0).strip(): if m and m.group(0).strip():
lines.append(m.group(0).strip()[:250]) lines.append(m.group(0).strip()[:250])
# 去重 # 去重
@@ -89,26 +135,32 @@ def zodiac_lookup(num):
return z[num % 12] return z[num % 12]
def analyze(): def analyze(period='082'):
"""082 期完整玄学分析 (按 reference 073 流程)""" """完整玄学分析 (按 reference 073 流程)
Args:
period: 期号 (默认 '082'), 用于 marker 匹配
"""
out = [] out = []
out.append("=" * 70) out.append("=" * 70)
out.append("082 期挂牌资料分析 (按 lottery-hk skill v1.2.4 流程)") out.append(f"{period} 期 4 框架玄学分析 (按 lottery-hk skill v1.2.7 流程)")
out.append("=" * 70) out.append("=" * 70)
out.append(f"📌 所有时间默认 {TIMEZONE_BEIJING}") out.append(f"📌 所有时间默认 {TIMEZONE_BEIJING}")
out.append(f"📌 挂牌日 = 实际开彩日 (sol.2344a.cc 帖子时间戳 = 实际开奖日)") out.append(f"📌 挂牌日 = 实际开彩日 (sol.2344a.cc 帖子时间戳 = 实际开奖日)")
out.append("") out.append("")
# ===== Step 1: v_xg.json ===== # ===== Step 1: v_xg.json =====
out.append("--- Step 1: v_xg.json (Qi=082, Data.1-7=080 已开 (Qi-2)) ---") out.append(f"--- Step 1: v_xg.json (Qi=最新已开, Data.1-7=Qi-2 已开) ---")
v = fetch_v_xg() v = fetch_v_xg()
data = v.get('Data', {}) data = v.get('Data', {})
qi = v.get('Qi', '?') qi = v.get('Qi', '?')
nq = v.get('Nq', '?') nq = v.get('Nq', '?')
week = v.get('Week', '?') week = v.get('Week', '?')
day = v.get('Day', '?') day = v.get('Day', '?')
out.append(f"Qi (下期) = {qi}, Nq (再下期) = {nq}") qi_minus_2 = int(qi) - 2 if qi.isdigit() else '?'
out.append(f"Qi 期开彩: {week} (Day={day}) = 082 期 {week} 21:30 {TIMEZONE_BEIJING}") out.append(f"Qi (最新已开) = {qi}, Nq (未开下期) = {nq}")
out.append(f"Qi 期开彩日(从 Nq 推算): Nq 期开彩日 Week={week} Day={day} - 3 天")
out.append(f"Data.1-7 = Qi-2 期 {qi_minus_2} 已开号码 (不是 Qi-1!)")
out.append("") out.append("")
out.append("| 位置 | 号码 | 生肖 | 五行 | 波色 |") out.append("| 位置 | 号码 | 生肖 | 五行 | 波色 |")
out.append("|---|---|---|---|---|") out.append("|---|---|---|---|---|")
@@ -126,28 +178,24 @@ def analyze():
last_seven.append({'num': num, 'sx': sx, 'nim': nim, 'color': color, 'pos': pos}) last_seven.append({'num': num, 'sx': sx, 'nim': nim, 'color': color, 'pos': pos})
out.append("") out.append("")
# 五行统计 # 五行统计
nims = [x['nim'] for x in last_seven]
sx_count = {}
for x in last_seven:
sx_count[x['sx']] = sx_count.get(x['sx'], 0) + 1
from collections import Counter from collections import Counter
nim_count = Counter(nims) nim_count = Counter([x['nim'] for x in last_seven])
out.append(f"081 期五行统计: " + " | ".join(f"{n}:{c}" for n, c in nim_count.most_common())) out.append(f"{qi_minus_2} 期五行统计: " + " | ".join(f"{n}:{c}" for n, c in nim_count.most_common()))
out.append(f"081 期生肖统计: " + " | ".join(f"{s}:{c}" for s, c in Counter([x['sx'] for x in last_seven]).most_common())) out.append(f"{qi_minus_2} 期生肖统计: " + " | ".join(f"{s}:{c}" for s, c in Counter([x['sx'] for x in last_seven]).most_common()))
out.append(f"081 期波色统计: " + " | ".join(f"{c}:{n}" for c, n in Counter([x['color'] for x in last_seven]).most_common())) out.append(f"{qi_minus_2} 期波色统计: " + " | ".join(f"{c}:{n}" for c, n in Counter([x['color'] for x in last_seven]).most_common()))
out.append("") out.append("")
# ===== Step 2: 综合挂牌 (列表 + 详情) ===== # ===== Step 2: 综合挂牌 (列表 + 详情) =====
out.append("--- Step 2: 综合挂牌 (sol.2344a.cc/zongheguapai/) ---") out.append(f"--- Step 2: 综合挂牌 (sol.2344a.cc/zongheguapai/) ---")
gua_list = fetch_sol_list('/zongheguapai/', '082', limit=3) gua_list = fetch_sol_list('/zongheguapai/', f'{period}', limit=3)
if gua_list: if gua_list:
for g in gua_list: for g in gua_list:
out.append(f"{g}") out.append(f"{g}")
out.append("") out.append("")
# 拿详情: 选第一个有 082 期的链接 # 拿详情: 选第一个有 period 的链接
import re import re
gua_html = curl_url(f'{SOL_BASE}/zongheguapai/') gua_html = curl_url(f'{SOL_BASE}/zongheguapai/')
detail_links = re.findall(r'href="(/zongheguapai/\d+\.html)"[^>]*>.*?082', gua_html)[:2] detail_links = re.findall(rf'href="(/zongheguapai/\d+\.html)"[^>]*>.*{period}', gua_html)[:2]
for link in detail_links: for link in detail_links:
fields = fetch_sol_detail(link) fields = fetch_sol_detail(link)
if fields: if fields:
@@ -157,14 +205,14 @@ def analyze():
out.append("") out.append("")
# ===== Step 3: 六信红字 ===== # ===== Step 3: 六信红字 =====
out.append("--- Step 3: 六信红字 (sol.2344a.cc/lxhz/) ---") out.append(f"--- Step 3: 六信红字 (sol.2344a.cc/lxhz/) ---")
hong_list = fetch_sol_list('/lxhz/', '082', limit=3) hong_list = fetch_sol_list('/lxhz/', f'{period}', limit=3)
if hong_list: if hong_list:
for h in hong_list: for h in hong_list:
out.append(f"{h}") out.append(f"{h}")
# 拿详情 # 拿详情
hong_html = curl_url(f'{SOL_BASE}/lxhz/') hong_html = curl_url(f'{SOL_BASE}/lxhz/')
hong_links = re.findall(r'href="(/lxhz/\d+\.html)"[^>]*>.*?082', hong_html)[:2] hong_links = re.findall(rf'href="(/lxhz/\d+\.html)"[^>]*>.*{period}', hong_html)[:2]
for link in hong_links: for link in hong_links:
fields = fetch_sol_detail(link) fields = fetch_sol_detail(link)
if fields: if fields:
@@ -174,8 +222,8 @@ def analyze():
out.append("") out.append("")
# ===== Step 4: 玄机诗 ===== # ===== Step 4: 玄机诗 =====
out.append("--- Step 4: 玄机诗 (sol.2344a.cc/xuanjiziliao/) ---") out.append(f"--- Step 4: 玄机诗 (sol.2344a.cc/xuanjiziliao/) ---")
xuan_list = fetch_sol_list('/xuanjiziliao/', '082', limit=5) xuan_list = fetch_sol_list('/xuanjiziliao/', f'{period}', limit=5)
if xuan_list: if xuan_list:
for x in xuan_list: for x in xuan_list:
out.append(f"{x}") out.append(f"{x}")
@@ -183,36 +231,48 @@ def analyze():
# ===== 综合 ===== # ===== 综合 =====
out.append("=" * 70) out.append("=" * 70)
out.append("082 期综合玄学共识") out.append(f"{period} 期综合玄学共识")
out.append("=" * 70) out.append("=" * 70)
out.append("") out.append("")
out.append("📊 081 期五行旺: " + (nim_count.most_common(1)[0][0] if nim_count else "") + " (3 次)") out.append(f"📊 {qi_minus_2} 期五行旺: " + (nim_count.most_common(1)[0][0] if nim_count else "") + " (3 次)")
out.append("📊 081 期生肖: 7 个全不重 (无明显旺)") out.append(f"📊 {qi_minus_2} 期生肖: 7 个全不重 (无明显旺)")
out.append("📊 081 期波色: " + (Counter([x['color'] for x in last_seven]).most_common(1)[0][0] if last_seven else "")) out.append(f"📊 {qi_minus_2} 期波色: " + (Counter([x['color'] for x in last_seven]).most_common(1)[0][0] if last_seven else ""))
out.append("") out.append("")
out.append("🔥 挂牌 + 红字 共识: 看上面挂牌内容") out.append(f"🔥 挂牌 + 红字 共识: 看上面挂牌内容")
out.append("") out.append("")
# ===== 082 期开彩 ===== # ===== 期开彩 =====
out.append("=" * 70) out.append("=" * 70)
out.append("🚨 082 期开彩") out.append(f"🚨 {period} 期开彩")
out.append("=" * 70) out.append("=" * 70)
out.append(f"日期: 2026-07-30") out.append(f"日期: 2026-{period[:2]}-{period[2:]}")
out.append(f"星期: {week}") out.append(f"星期: {week}")
out.append(f"时间: 21:30 {TIMEZONE_BEIJING}") out.append(f"时间: 21:30 {TIMEZONE_BEIJING}")
out.append("") out.append("")
out.append("下期 083 期将于 2026-08-01 (周六) 21:30 北京时间开彩")
out.append("")
out.append("数据来源:") out.append("数据来源:")
out.append(" 1. btc.tktk.app/data/v_xg.json") out.append(" 1. btc.tktk.app/data/v_xg.json")
out.append(f" 2. {SOL_BASE}/zongheguapai/ (综合挂牌)") out.append(f" 2. {SOL_BASE}/zongheguapai/ (综合挂牌)")
out.append(f" 3. {SOL_BASE}/lxhz/ (六信红字)") out.append(f" 3. {SOL_BASE}/lxhz/ (六信红字)")
out.append(f" 4. {SOL_BASE}/xuanjiziliao/ (玄机诗)") out.append(f" 4. {SOL_BASE}/xuanjiziliao/ (玄机诗)")
out.append("") out.append("")
out.append(f"参考: skill lottery-hk v1.2.4, references/analysis-example-073/074/075.md") out.append(f"参考: skill lottery-hk v1.2.7, references/analysis-example-073/074/075.md")
return '\n'.join(out) return '\n'.join(out)
if __name__ == '__main__': if __name__ == '__main__':
print(analyze()) import urllib.request, json as _json
period = sys.argv[1] if len(sys.argv) > 1 else None
if period is None:
try:
req = urllib.request.Request('https://btc.tktk.app/data/v_xg.json',
headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=10) as r:
period = _json.loads(r.read().decode('utf-8')).get('Qi', '???')
except Exception:
period = '???'
try:
print(analyze(period))
except RuntimeError as e:
print(f"\n❌ ERR: {e}", file=sys.stderr)
sys.exit(1)