From 4ee6a2e1952e61602580f55b10a5bed9a36dec50 Mon Sep 17 00:00:00 2001 From: hkyc Date: Thu, 22 May 2025 22:30:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0IMAP=E9=82=AE=E4=BB=B6?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E5=8A=9F=E8=83=BD=E5=92=8C=E8=B4=A6=E6=88=B7?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProxyPool.py | 59 ++ PynoCaptchaSolver.py | 83 ++ RegistrationGUIWithPynoV2.py | 578 +++++++++++ SteamCaptchaHelper.py | 113 +++ SteamRegistrationWithPyno.py | 911 ++++++++++++++++++ ThreadManagerWithPyno.py | 155 +++ __pycache__/ProxyPool.cpython-312.pyc | Bin 0 -> 3508 bytes __pycache__/PynoCaptchaSolver.cpython-312.pyc | Bin 0 -> 3802 bytes .../RegistrationGUIWithPynoV2.cpython-312.pyc | Bin 0 -> 31178 bytes .../SteamCaptchaHelper.cpython-312.pyc | Bin 0 -> 5081 bytes .../SteamRegistrationWithPyno.cpython-312.pyc | Bin 0 -> 44602 bytes .../ThreadManagerWithPyno.cpython-312.pyc | Bin 0 -> 8684 bytes accounts_succ.txt | 1 + config.json | 12 + email_password.txt | 1 + proxy_ips.txt | 1 + rgerror.txt | 1 + start_pyno_v3.py | 17 + steam_registration_pyno.log | 179 ++++ test_imap.py | 203 ++++ 启动Steam注册.bat | 5 + 21 files changed, 2319 insertions(+) create mode 100644 ProxyPool.py create mode 100644 PynoCaptchaSolver.py create mode 100644 RegistrationGUIWithPynoV2.py create mode 100644 SteamCaptchaHelper.py create mode 100644 SteamRegistrationWithPyno.py create mode 100644 ThreadManagerWithPyno.py create mode 100644 __pycache__/ProxyPool.cpython-312.pyc create mode 100644 __pycache__/PynoCaptchaSolver.cpython-312.pyc create mode 100644 __pycache__/RegistrationGUIWithPynoV2.cpython-312.pyc create mode 100644 __pycache__/SteamCaptchaHelper.cpython-312.pyc create mode 100644 __pycache__/SteamRegistrationWithPyno.cpython-312.pyc create mode 100644 __pycache__/ThreadManagerWithPyno.cpython-312.pyc create mode 100644 accounts_succ.txt create mode 100644 config.json create mode 100644 email_password.txt create mode 100644 proxy_ips.txt create mode 100644 rgerror.txt create mode 100644 start_pyno_v3.py create mode 100644 steam_registration_pyno.log create mode 100644 test_imap.py create mode 100644 启动Steam注册.bat diff --git a/ProxyPool.py b/ProxyPool.py new file mode 100644 index 0000000..9ad14a0 --- /dev/null +++ b/ProxyPool.py @@ -0,0 +1,59 @@ +import queue +import time + +class ProxyPool: + """代理IP池管理""" + def __init__(self, proxy_file_path): + self.proxy_queue = queue.Queue() + self.success_queue = queue.Queue() + self._load_proxies(proxy_file_path) + + def _load_proxies(self, file_path): + """加载代理IP""" + try: + with open(file_path, "r") as file: + proxy_ips = [line.strip() for line in file if line.strip()] + self.proxy_count = len(proxy_ips) + if self.proxy_count == 0: + raise ValueError("代理文件为空") + for proxy in proxy_ips: + self.proxy_queue.put(proxy) + except FileNotFoundError: + raise FileNotFoundError(f"代理文件不存在: {file_path}") + except Exception as e: + raise Exception(f"加载代理文件失败: {str(e)}") + + def get_proxy(self): + """获取代理IP""" + max_retries = 12 # 最大等待时间60秒 + retries = 0 + + while retries < max_retries: + try: + if not self.success_queue.empty(): + return self.success_queue.get(block=False) + + if not self.proxy_queue.empty(): + return self.proxy_queue.get(block=True, timeout=5) + + if self.proxy_count == 0: + raise ValueError("无可用代理") + + retries += 1 + time.sleep(5) + + except queue.Empty: + continue + except Exception as e: + print(f"获取代理失败: {e}") + time.sleep(1) + + raise TimeoutError("获取代理超时") + + def mark_success(self, proxy): + """标记成功的代理""" + self.success_queue.put(proxy) + + def mark_fail(self, proxy): + """标记失败的代理""" + self.proxy_queue.put(proxy) \ No newline at end of file diff --git a/PynoCaptchaSolver.py b/PynoCaptchaSolver.py new file mode 100644 index 0000000..79e9bb4 --- /dev/null +++ b/PynoCaptchaSolver.py @@ -0,0 +1,83 @@ +from dataclasses import dataclass +from typing import Dict, Optional + +from pynocaptcha import HcaptchaCracker +from loguru import logger + + +@dataclass +class PynoCaptchaConfig: + user_token: str + sitekey: str = "8cf23430-f9c8-4aaa-9ba2-da32f65adf2e" # 默认值 + referer: str = "https://store.steampowered.com/join/" + timeout: int = 60 + debug: bool = True + user_agent: str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36" + + +class PynoCaptchaSolver: + def __init__(self, config: PynoCaptchaConfig): + self.config = config + logger.debug(f"PynoCaptchaSolver 初始化 - 使用 PyNoCaptcha 库") + + def solve_hcaptcha(self) -> Optional[Dict]: + """ + 使用 PyNoCaptcha 库解决 HCaptcha 验证码 + + 返回: + 成功时返回包含验证结果的字典,失败时返回None + """ + try: + logger.debug(f"开始解决验证码 - sitekey: {self.config.sitekey}") + logger.debug(f"使用User-Agent: {self.config.user_agent}") + + # 创建验证码破解器 + cracker = HcaptchaCracker( + user_token=self.config.user_token, + sitekey=self.config.sitekey, + referer=self.config.referer, + user_agent=self.config.user_agent, + debug=self.config.debug, + timeout=self.config.timeout, + ) + + # 破解验证码 + logger.debug("调用 PyNoCaptcha 进行破解") + result = cracker.crack() + + if result: + logger.debug("验证码破解成功") + return { + "captcha_text": result.get("generated_pass_UUID"), + "token": result.get("generated_pass_UUID"), + "solution": result + } + else: + logger.error("验证码破解失败") + return None + + except Exception as e: + logger.error(f"验证码破解过程中出错: {str(e)}") + return None + + +# 使用示例 +if __name__ == "__main__": + # 配置 + config = PynoCaptchaConfig( + user_token="cf169d36-0d62-45da-bff7-1eff42bbc4f3", + sitekey="8cf23430-f9c8-4aaa-9ba2-da32f65adf2e", + referer="https://store.steampowered.com/join/", + user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36" + ) + + # 初始化求解器 + solver = PynoCaptchaSolver(config) + + # 解决验证码 + result = solver.solve_hcaptcha() + + if result: + print(f"验证成功: {result['captcha_text'][:30]}...") + else: + print("验证失败") \ No newline at end of file diff --git a/RegistrationGUIWithPynoV2.py b/RegistrationGUIWithPynoV2.py new file mode 100644 index 0000000..4ee7adb --- /dev/null +++ b/RegistrationGUIWithPynoV2.py @@ -0,0 +1,578 @@ +import json +import os +import tkinter as tk +from tkinter import ttk +import threading +from tkinter import messagebox +from tkinter import filedialog +from ThreadManagerWithPyno import GUIThreadManagerWithPyno +from PynoCaptchaSolver import PynoCaptchaConfig, PynoCaptchaSolver +from SteamCaptchaHelper import SteamCaptchaHelper +import time + +# 配置日志 +from loguru import logger +logger.add("steam_registration_pyno.log", rotation="10 MB") + +class RegistrationGUIWithPynoV2: + def __init__(self, root): + self.root = root + self.root.title("Steam注册 - PyNoCaptcha V2") + self.root.geometry("800x800") + self.root.minsize(800, 800) # 设置最小窗口大小 + + # 创建主框架 + main_frame = ttk.Frame(root) + main_frame.pack(fill="both", expand=True, padx=10, pady=5) + + # 顶部框架 - 包含所有输入配置 + top_frame = ttk.Frame(main_frame) + top_frame.pack(fill="x", side="top", padx=5, pady=5) + + # 创建配置框架 + config_frame = ttk.LabelFrame(top_frame, text="配置信息") + config_frame.pack(fill="x", padx=5, pady=5) + + # 加载默认配置 + self.script_dir = os.path.dirname(os.path.abspath(__file__)) + self.config_path = os.path.join(self.script_dir, 'config.json') + self.config = self._load_config() + + # 创建配置输入框 + self.config_vars = {} + self._create_config_widgets(config_frame) + + # 创建PyNoCaptcha配置框架 + captcha_frame = ttk.LabelFrame(top_frame, text="PyNoCaptcha配置") + captcha_frame.pack(fill="x", padx=5, pady=5) + + # 创建PyNoCaptcha配置输入框 + self.captcha_vars = {} + self._create_captcha_widgets(captcha_frame) + + # 创建Steam状态框架 + steam_frame = ttk.LabelFrame(top_frame, text="Steam验证状态") + steam_frame.pack(fill="x", padx=5, pady=5) + + # 添加Steam状态信息 + self.steam_status_var = tk.StringVar(value="未获取验证信息") + self.steam_sitekey_var = tk.StringVar(value="未获取sitekey") + self.steam_gid_var = tk.StringVar(value="未获取gid") + + ttk.Label(steam_frame, text="状态:").grid(row=0, column=0, padx=5, pady=2, sticky="e") + ttk.Label(steam_frame, textvariable=self.steam_status_var).grid(row=0, column=1, padx=5, pady=2, sticky="w") + + ttk.Label(steam_frame, text="SiteKey:").grid(row=1, column=0, padx=5, pady=2, sticky="e") + ttk.Label(steam_frame, textvariable=self.steam_sitekey_var).grid(row=1, column=1, padx=5, pady=2, sticky="w") + + ttk.Label(steam_frame, text="GID:").grid(row=2, column=0, padx=5, pady=2, sticky="e") + ttk.Label(steam_frame, textvariable=self.steam_gid_var).grid(row=2, column=1, padx=5, pady=2, sticky="w") + + ttk.Button(steam_frame, text="刷新验证信息", + command=self._refresh_steam_info).grid(row=3, column=0, columnspan=2, padx=5, pady=5) + + # 创建文件选择框架 + files_frame = ttk.LabelFrame(top_frame, text="文件选择") + files_frame.pack(fill="x", padx=5, pady=5) + + # 邮箱文件选择 + self.email_path = tk.StringVar(value=os.path.join(self.script_dir, 'email_password.txt')) + self._create_file_selector(files_frame, "邮箱文件:", self.email_path, 0) + + # 代理文件选择 + self.proxy_path = tk.StringVar(value=os.path.join(self.script_dir, 'proxy_ips.txt')) + self._create_file_selector(files_frame, "代理文件:", self.proxy_path, 1) + + # 按钮框架 - 直接放在主界面上,任务列表上方 + button_frame = ttk.Frame(main_frame) + button_frame.pack(fill="x", padx=5, pady=10) + + # 添加开始按钮 + self.start_button = ttk.Button( + button_frame, + text="开始注册", + command=self.start_registration, + width=20 + ) + self.start_button.pack(side="left", padx=10, pady=5, expand=True) + + # 添加停止按钮 + self.stop_button = ttk.Button( + button_frame, + text="停止注册", + command=self.stop_registration, + state="disabled", + width=20 + ) + self.stop_button.pack(side="left", padx=10, pady=5, expand=True) + + # 添加测试验证码按钮 + self.test_captcha_button = ttk.Button( + button_frame, + text="测试验证码", + command=self.test_captcha, + width=20 + ) + self.test_captcha_button.pack(side="left", padx=10, pady=5, expand=True) + + # 中间框架 - 包含任务状态表格 + middle_frame = ttk.Frame(main_frame) + middle_frame.pack(fill="both", expand=True, padx=5, pady=5) + + # 创建任务列表框架 + task_frame = ttk.LabelFrame(middle_frame, text="任务状态") + task_frame.pack(fill="both", expand=True, padx=5, pady=5) + + # 创建表格框架 + table_frame = ttk.Frame(task_frame) + table_frame.pack(fill="both", expand=True, padx=5, pady=5) + + self.tree = ttk.Treeview(table_frame, columns=("邮箱", "状态", "账户名", "密码", "结果"), show="headings") + + # 设置列头 + self.tree.heading("邮箱", text="邮箱") + self.tree.heading("状态", text="状态") + self.tree.heading("账户名", text="账户名") + self.tree.heading("密码", text="密码") + self.tree.heading("结果", text="结果") + + # 设置列宽 + self.tree.column("邮箱", width=200) + self.tree.column("状态", width=200) + self.tree.column("账户名", width=100) + self.tree.column("密码", width=100) + self.tree.column("结果", width=100) + + # 添加滚动条 + scrollbar = ttk.Scrollbar(table_frame, orient="vertical", command=self.tree.yview) + self.tree.configure(yscrollcommand=scrollbar.set) + + # 布局 + self.tree.pack(side="left", fill="both", expand=True) + scrollbar.pack(side="right", fill="y") + + # 存储线程状态 + self.thread_status = {} + + # 存储Steam验证信息 + self.steam_data = None + self.steam_helper = SteamCaptchaHelper() + + # 添加进度控制变量 + self._stop_progress_update = False + + # 添加版本标签 + version_label = ttk.Label(main_frame, text="PyNoCaptcha V2 版本", foreground="blue") + version_label.pack(side="bottom", padx=5, pady=5) + + def _refresh_steam_info(self): + """刷新Steam验证信息""" + threading.Thread(target=self._refresh_steam_info_thread, daemon=True).start() + + def _refresh_steam_info_thread(self): + """在新线程中刷新Steam验证信息""" + try: + self.steam_status_var.set("正在获取Steam验证信息...") + self.steam_data = self.steam_helper.get_sitekey() + + if self.steam_data: + self.steam_status_var.set("获取验证信息成功") + self.steam_sitekey_var.set(self.steam_data["sitekey"]) + self.steam_gid_var.set(self.steam_data["gid"]) + + # 更新验证码配置中的sitekey + self.captcha_vars["pyno_sitekey"].set(self.steam_data["sitekey"]) + # 更新User-Agent + self.captcha_vars["pyno_user_agent"].set(self.steam_helper.get_user_agent()) + else: + self.steam_status_var.set("获取验证信息失败") + except Exception as e: + logger.error(f"刷新Steam信息出错: {str(e)}") + self.steam_status_var.set(f"错误: {str(e)}") + + def _load_config(self): + """加载配置文件""" + try: + with open(self.config_path, 'r') as f: + return json.load(f) + except Exception as e: + messagebox.showerror("错误", f"加载配置文件失败: {str(e)}") + return {} + + def _create_config_widgets(self, parent): + """创建配置输入控件""" + config_items = [ + ("protocol", "协议类型:", ["GRAPH", "IMAP", "POP3", "IMAP_OAUTH", "POP3_OAUTH"]), + ("ssl", "启用SSL:", ["True", "False"]), + ("email_url", "邮箱服务器:", None), + ("executornum", "线程数量:", None) + ] + + for i, (key, label, options) in enumerate(config_items): + ttk.Label(parent, text=label,width=10).grid(row=i, column=0, padx=5, pady=2, sticky="e") + + if options: + var = tk.StringVar(value=str(self.config.get(key, ""))) + widget = ttk.Combobox(parent, textvariable=var, values=options,width=50) + else: + var = tk.StringVar(value=str(self.config.get(key, ""))) + widget = ttk.Entry(parent, textvariable=var, width=50) + + widget.grid(row=i, column=1, padx=5, pady=2, sticky="ew") + self.config_vars[key] = var + + def _create_captcha_widgets(self, parent): + """创建PyNoCaptcha配置输入控件""" + captcha_items = [ + ("pyno_user_token", "PyNoCaptcha API密钥:", None), + ("pyno_sitekey", "验证码网站Key:", None), + ("pyno_referer", "网站Referer:", None), + ("pyno_user_agent", "User-Agent:", None), + ("pyno_timeout", "超时时间(秒):", None), + ("pyno_debug", "调试模式:", ["True", "False"]) + ] + + for i, (key, label, options) in enumerate(captcha_items): + ttk.Label(parent, text=label,width=12).grid(row=i, column=0, padx=5, pady=2, sticky="e") + + if options: + var = tk.StringVar(value=str(self.config.get(key, "True" if key == "pyno_debug" else "False"))) + widget = ttk.Combobox(parent, textvariable=var, values=options,width=50) + else: + default_value = "" + if key == "pyno_sitekey": + default_value = "8cf23430-f9c8-4aaa-9ba2-da32f65adf2e" + elif key == "pyno_referer": + default_value = "https://store.steampowered.com/join/" + elif key == "pyno_timeout": + default_value = "60" + elif key == "pyno_user_agent": + default_value = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36" + + var = tk.StringVar(value=str(self.config.get(key, default_value))) + widget = ttk.Entry(parent, textvariable=var, width=50) + + widget.grid(row=i, column=1, padx=5, pady=2, sticky="ew") + self.captcha_vars[key] = var + + def _create_file_selector(self, parent, label, var, row): + """创建文件选择器""" + parent.grid_columnconfigure(1, weight=1) + ttk.Label(parent, text=label).grid(row=row, column=0, padx=5, pady=2, sticky="e") + ttk.Entry(parent, textvariable=var).grid(row=row, column=1, padx=5, pady=2, sticky="ew") + ttk.Button(parent, text="选择文件", + command=lambda: var.set(filedialog.askopenfilename()) + ).grid(row=row, column=2, padx=5, pady=2) + + def update_status(self, email, status=None, account_name=None, password=None, result=None): + """更新任务状态 + + Args: + email: 邮箱地址 + status: 当前状态 + account_name: 账户名 + password: 密码 + result: 结果 + """ + try: + # 防止值中包含taskId等敏感信息 + if status and isinstance(status, str) and 'taskId' in status: + status = "正在处理验证码..." + + if email not in self.thread_status: + # 新建条目,将None替换为空字符串 + values = ( + email, + status if status is not None else "", + account_name if account_name is not None else "", + password if password is not None else "", + result if result is not None else "" + ) + self.thread_status[email] = self.tree.insert("", "end", values=values) + else: + # 获取当前值 + current_values = list(self.tree.item(self.thread_status[email])['values']) + + # 只更新非None的值 + if status is not None: + current_values[1] = status + if account_name is not None: + current_values[2] = account_name + if password is not None: + current_values[3] = password + if result is not None: + current_values[4] = result + + # 更新现有条目 + self.tree.item(self.thread_status[email], values=tuple(current_values)) + + # 更新界面 + self.root.update() + except Exception as e: + # 如果更新UI出错,至少在控制台输出信息 + print(f"更新界面时出错: {e}") + + def get_completed_tasks(self): + """获取已经完成的任务列表""" + completed_tasks = set() + for email in self.thread_status: + values = self.tree.item(self.thread_status[email])['values'] + if values[4]: # 检查result列是否有值 + completed_tasks.add(email) + return completed_tasks + + def _save_config(self): + """保存配置""" + try: + config = {} + # 保存原有配置 + for key, var in self.config_vars.items(): + value = var.get() + if key == "executornum": + value = int(value) + elif key == "ssl": + value = value.lower() == "true" + config[key] = value + + # 保存PyNoCaptcha配置 + for key, var in self.captcha_vars.items(): + value = var.get() + if key == "pyno_timeout": + value = int(value) + elif key == "pyno_debug": + value = value.lower() == "true" + config[key] = value + + with open(self.config_path, 'w') as f: + json.dump(config, f, indent=2) + return True + except Exception as e: + messagebox.showerror("错误", f"保存配置失败: {str(e)}") + return False + + def _validate_inputs(self): + """验证输入""" + if not os.path.exists(self.email_path.get()): + messagebox.showerror("错误", "邮箱文件不存在") + return False + + if not os.path.exists(self.proxy_path.get()): + messagebox.showerror("错误", "代理文件不存在") + return False + + # 验证基本配置 + for key, var in self.config_vars.items(): + if not var.get().strip(): + messagebox.showerror("错误", f"请填写 {key} 配置项") + return False + + # 验证PyNoCaptcha配置 + required_captcha_keys = ["pyno_user_token"] + for key in required_captcha_keys: + if not self.captcha_vars[key].get().strip(): + messagebox.showerror("错误", f"请填写 {key} 配置项") + return False + + return True + + def get_captcha_config(self): + """获取PyNoCaptcha配置""" + return PynoCaptchaConfig( + user_token=self.captcha_vars["pyno_user_token"].get(), + sitekey=self.captcha_vars["pyno_sitekey"].get(), + referer=self.captcha_vars["pyno_referer"].get(), + user_agent=self.captcha_vars["pyno_user_agent"].get(), + timeout=int(self.captcha_vars["pyno_timeout"].get()), + debug=self.captcha_vars["pyno_debug"].get().lower() == "true" + ) + + def test_captcha(self): + """测试PyNoCaptcha验证码""" + # 验证配置 + if not self.captcha_vars["pyno_user_token"].get().strip(): + messagebox.showerror("错误", "请先填写PyNoCaptcha API密钥") + return + + # 保存配置 + if not self._save_config(): + return + + # 禁用测试按钮 + self.test_captcha_button.config(state="disabled") + + # 在新线程中测试 + threading.Thread(target=self._test_captcha_thread, daemon=True).start() + + def _test_captcha_thread(self): + """在新线程中测试PyNoCaptcha""" + try: + test_id = "测试PyNoCaptcha" + self.update_status(test_id, status="正在准备验证码测试...") + + # 首先获取动态sitekey + self.update_status(test_id, status="正在获取Steam验证信息...") + steam_data = self.steam_helper.get_sitekey() + + if not steam_data: + self.update_status(test_id, status="获取验证信息失败", result="失败") + messagebox.showerror("错误", "获取Steam验证信息失败") + return + + # 更新界面上的sitekey + self.steam_sitekey_var.set(steam_data["sitekey"]) + self.steam_gid_var.set(steam_data["gid"]) + self.steam_status_var.set("获取验证信息成功") + + # 更新验证码配置 + self.captcha_vars["pyno_sitekey"].set(steam_data["sitekey"]) + self.captcha_vars["pyno_user_agent"].set(self.steam_helper.get_user_agent()) + self._save_config() + + # 获取配置 + config = self.get_captcha_config() + + # 创建求解器 + solver = PynoCaptchaSolver(config) + + # 更新状态 + self.update_status(test_id, status="正在尝试解决验证码...") + + # 解决验证码 - 每秒更新进度状态 + progress_thread = threading.Thread( + target=self._update_captcha_progress, + args=(test_id,), + daemon=True + ) + progress_thread.start() + + # 解决验证码 + result = solver.solve_hcaptcha() + + # 停止进度更新 + self._stop_progress_update = True + + if not result: + messagebox.showerror("失败", "验证码解决失败") + self.update_status(test_id, status="验证码解决失败", result="失败") + return + + self.update_status(test_id, status="验证码解决成功") + token_preview = result.get("captcha_text", "")[:30] + "..." if result.get("captcha_text") else "无令牌" + self.update_status(test_id, status=f"验证码解决成功: {token_preview}") + + # 尝试验证邮箱 + self.update_status(test_id, status="正在验证邮箱...") + captcha_text = result.get("captcha_text") + verify_result = self.steam_helper.verify_email( + "749army@gmail.com", + captcha_text, + steam_data["init_id"], + steam_data["gid"] + ) + + if verify_result.get("success") == 1: + messagebox.showinfo("成功", "验证邮箱成功!") + self.update_status(test_id, status="验证成功", result="通过") + else: + error_msg = verify_result.get('details', verify_result.get('error', '未知错误')) + messagebox.showerror("失败", f"验证邮箱失败: {error_msg}") + self.update_status(test_id, status=f"验证失败: {error_msg}", result="失败") + + except Exception as e: + logger.error(f"测试过程中出错: {str(e)}") + messagebox.showerror("错误", f"测试过程中出错: {str(e)}") + self.update_status("测试PyNoCaptcha", status=f"出错: {str(e)}", result="错误") + finally: + # 恢复按钮状态 + self.test_captcha_button.config(state="normal") + # 确保停止进度更新 + self._stop_progress_update = True + + def _update_captcha_progress(self, test_id): + """更新验证码进度显示""" + self._stop_progress_update = False + progress_chars = ["|", "/", "-", "\\"] + i = 0 + while not self._stop_progress_update: + self.update_status(test_id, status=f"正在尝试解决验证码... {progress_chars[i]}") + time.sleep(0.5) + i = (i + 1) % len(progress_chars) + + def start_registration(self): + """启动注册流程""" + try: + if not self._validate_inputs(): # 添加输入验证 + return + + if not self._save_config(): + return + + if hasattr(self, 'manager') and self.manager: + messagebox.showwarning("警告", "任务已在运行中") + return + + self.start_button.config(state="disabled") + self.stop_button.config(state="normal") + + threading.Thread(target=self._start_registration_thread, + daemon=True, + name="RegistrationThread").start() + except Exception as e: + messagebox.showerror("错误", f"启动失败: {str(e)}") + self.start_button.config(state="normal") + self.stop_button.config(state="disabled") + + def _start_registration_thread(self): + """在新线程中启动注册""" + try: + completed_tasks = self.get_completed_tasks() + + # 获取验证码配置并保存到config.json + try: + # 先获取最新的Steam验证信息 + steam_data = self.steam_helper.get_sitekey() + if steam_data: + self.steam_sitekey_var.set(steam_data["sitekey"]) + self.steam_gid_var.set(steam_data["gid"]) + self.steam_status_var.set("获取验证信息成功") + + # 更新验证码配置 + self.captcha_vars["pyno_sitekey"].set(steam_data["sitekey"]) + self.captcha_vars["pyno_user_agent"].set(self.steam_helper.get_user_agent()) + + # 保存配置 + if not self._save_config(): + return + except Exception as e: + messagebox.showerror("错误", f"获取Steam验证信息失败: {str(e)}") + return + + # 使用PyNoCaptcha版本的GUIThreadManager + self.manager = GUIThreadManagerWithPyno( + self.config_path, + self.email_path.get(), + self.proxy_path.get(), + self, + completed_tasks + ) + self.manager.start() + + except Exception as e: + messagebox.showerror("错误", str(e)) + finally: + self.start_button.config(state="normal") + self.stop_button.config(state="disabled") + + def stop_registration(self): + """停止注册流程""" + if hasattr(self, 'manager'): + self.manager.stop() + self.start_button.config(state="normal") + self.stop_button.config(state="disabled") + +if __name__ == "__main__": + root = tk.Tk() + gui = RegistrationGUIWithPynoV2(root) + # 启动时自动刷新Steam信息 + threading.Thread(target=gui._refresh_steam_info_thread, daemon=True).start() + root.mainloop() \ No newline at end of file diff --git a/SteamCaptchaHelper.py b/SteamCaptchaHelper.py new file mode 100644 index 0000000..1c54b03 --- /dev/null +++ b/SteamCaptchaHelper.py @@ -0,0 +1,113 @@ +import requests +from lxml import etree +from loguru import logger + +class SteamCaptchaHelper: + def __init__(self): + # 使用标准的Steam请求头 + self.headers = { + "Host": "store.steampowered.com", + "X-Prototype-Version": "1.7", + "sec-ch-ua-platform": "\"Windows\"", + "sec-ch-ua": "\"Chromium\";v=\"130\", \"Google Chrome\";v=\"130\", \"Not?A_Brand\";v=\"99\"", + "sec-ch-ua-mobile": "?0", + "X-Requested-With": "XMLHttpRequest", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36", + "Accept": "text/javascript, text/html, application/xml, text/xml, */*", + "Content-type": "application/x-www-form-urlencoded; charset=UTF-8", + "Origin": "https://store.steampowered.com", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Dest": "empty", + "Referer": "https://store.steampowered.com/join/", + "Accept-Language": "zh-CN,zh;q=0.9" + } + self.session = requests.Session() + self.session.headers.update(self.headers) + + def get_sitekey(self): + """获取Steam网站的sitekey和其他必要信息""" + try: + # 获取初始页面 + logger.info("获取Steam注册页面...") + url = "https://store.steampowered.com/join/" + response = self.session.get(url, verify=False) + html = etree.HTML(response.text) + + # 提取init_id + init_id = html.xpath('//input[@name="init_id"]/@value') + if init_id: + init_id = init_id[0] + logger.info(f"获取init_id成功: {init_id}") + else: + logger.error("无法获取init_id") + return None + + # 刷新验证码获取sitekey + logger.info("刷新验证码获取sitekey...") + url = "https://store.steampowered.com/join/refreshcaptcha/" + data = {"count": "1", "hcaptcha": "1"} + response = self.session.post(url, data=data, verify=False) + result = response.json() + + gid = result.get("gid") + sitekey = result.get("sitekey") + + logger.info(f"获取gid成功: {gid}") + logger.info(f"获取sitekey成功: {sitekey}") + + return { + "session": self.session, + "init_id": init_id, + "gid": gid, + "sitekey": sitekey + } + except Exception as e: + logger.error(f"获取sitekey过程中出错: {str(e)}") + return None + + def verify_email(self, email, captcha_text, init_id, gid): + """验证邮箱步骤""" + try: + logger.info(f"验证邮箱: {email}") + url = "https://store.steampowered.com/join/ajaxverifyemail" + + post_data = { + "email": email, + "captchagid": gid, + "captcha_text": captcha_text, + "elang": "6", + "init_id": init_id, + "guest": "false" + } + + response = self.session.post(url, data=post_data, verify=False) + result = response.json() + + logger.info(f"验证邮箱结果: {result}") + + # 检查不同的响应类型 + # 1 表示成功 + # 17 可能是"创建Steam账户时发生错误" + # 其他失败情况 + if 'success' not in result: + result['success'] = 0 + result['error'] = "无效的响应" + + return result + except Exception as e: + logger.error(f"验证邮箱过程中出错: {str(e)}") + return {"success": 0, "error": str(e)} + + def get_user_agent(self): + """返回Steam的用户代理""" + return self.headers["User-Agent"] + +# 使用示例 +if __name__ == "__main__": + helper = SteamCaptchaHelper() + data = helper.get_sitekey() + if data: + print(f"成功获取sitekey: {data['sitekey']}") + else: + print("获取sitekey失败") \ No newline at end of file diff --git a/SteamRegistrationWithPyno.py b/SteamRegistrationWithPyno.py new file mode 100644 index 0000000..a8a930c --- /dev/null +++ b/SteamRegistrationWithPyno.py @@ -0,0 +1,911 @@ +import base64 +import imaplib +import json +import os +import poplib +import random +import re +import string +import time +import threading +from urllib.parse import urlparse, parse_qs +import requests +from bs4 import BeautifulSoup +import tkinter as tk +import email +import email.header +from email.parser import BytesParser +from email.policy import default +from PynoCaptchaSolver import PynoCaptchaConfig, PynoCaptchaSolver +from loguru import logger +from SteamCaptchaHelper import SteamCaptchaHelper + +class SteamRegistrationWithPyno: + """Steam注册处理器 - 使用PyNoCaptcha解决验证码""" + def __init__(self, config, proxy_pool): + self.config = config + self.proxy_pool = proxy_pool + self.script_dir = os.path.dirname(os.path.abspath(__file__)) + self._file_lock = threading.Lock() + self._session_local = threading.local() + self.email_data = None + self.session = None + self.proxy_info = None + self.cookie_str = None + self.token = None + self.access_token = None + self.gid = None + self.init_id = None + self.sessionid = None + self.gui = None + self.running = True + self._steam_gid = None + self._steam_init_id = None + self._steam_sitekey = None + self.BASE_HEADERS = { + "Accept": "*/*", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0", + "Referer": "https://store.steampowered.com/join/", + "Origin": "https://store.steampowered.com", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", + "Sec-Fetch-Dest": "empty", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Site": "same-origin", + "sec-ch-ua": '"Microsoft Edge";v="125"', + "sec-ch-ua-mobile": "?0", + "sec-ch-ua-platform": '"Windows"' + } + if not hasattr(self._session_local, 'session'): + self._session_local.session = requests.Session() + self._session_local.session.headers.update(self.BASE_HEADERS) + + def set_gui(self, gui): + self.gui = gui + + def update_status(self, status, account_name=None, password=None, result=None): + if self.gui: + self.gui.update_status(self.email_data['email'], status, account_name, password, result) + + def is_email_valid(self): + """验证邮箱有效性""" + try: + protocol = self.config['protocol'] + email_url = self.config['email_url'] + use_ssl = self.config['ssl'] + email = self.email_data['email'] + password = self.email_data['password'] + if protocol == "IMAP": + server = imaplib.IMAP4_SSL(email_url) if use_ssl else imaplib.IMAP4(email_url) + server.login(email, password) + server.logout() + elif protocol == "POP3": + server = poplib.POP3_SSL(email_url) if use_ssl else poplib.POP3(email_url) + server.user(email) + server.pass_(password) + server.quit() + elif protocol == "GRAPH": + self._get_access_token() + if not self.access_token: + raise ValueError("获取访问令牌失败") + emails = self._graph_get_email() + if emails is None: + raise ValueError("获取邮件失败") + elif protocol == "IMAP_OAUTH": + self._get_access_token() + if not self.access_token: + raise ValueError("获取访问令牌失败") + server = self._authenticate_oauth2() + server.logout() + elif protocol == "POP3_OAUTH": + self._get_access_token() + if not self.access_token: + raise ValueError("获取访问令牌失败") + server = self._authenticate_oauth2() + server.quit() + else: + raise ValueError("不支持的协议类型") + return True + except Exception as e: + print(f"{email},邮箱验证失败: {e}") + return False + + def _get_access_token(self): + """获取OAuth访问令牌""" + data = { + 'client_id': self.email_data['client_id'], + 'refresh_token': self.email_data['refresh_token'], + 'grant_type': 'refresh_token', + } + if self.config['protocol'] == 'GRAPH': + data['scope'] = 'https://graph.microsoft.com/.default' + response = requests.post( + 'https://login.microsoftonline.com/consumers/oauth2/v2.0/token', + data=data + ) + if response.status_code == 200: + result = response.json() + access_token = result.get('access_token') + refresh_token = result.get('refresh_token') + if refresh_token and refresh_token != self.email_data['refresh_token']: + self.email_data['refresh_token'] = refresh_token + self._update_refresh_token(refresh_token) + self.access_token = access_token + + def _authenticate_oauth2(self): + """OAuth2认证""" + email = self.email_data['email'] + auth_string = f"user={email}\x01auth=Bearer {self.access_token}\x01\x01" + auth_bytes = auth_string.encode('ascii') + auth_b64 = base64.b64encode(auth_bytes).decode('ascii') + + if self.config['protocol'] == "IMAP_OAUTH": + server = imaplib.IMAP4_SSL('outlook.office365.com', 993) + server.authenticate('XOAUTH2', lambda x: auth_string) + return server + elif self.config['protocol'] == "POP3_OAUTH": + server = poplib.POP3_SSL('outlook.office365.com', 995) + server._shortcmd('AUTH XOAUTH2') + server._shortcmd(auth_b64) + return server + + def _graph_get_email(self): + try: + if not self.access_token: + return None + headers = { + 'Authorization': f'Bearer {self.access_token}', + 'Content-Type': 'application/json' + } + + params = { + '$top': 5, + '$select': 'subject,body,receivedDateTime,from,hasAttachments', + '$orderby': 'receivedDateTime desc' + } + + response = requests.get('https://graph.microsoft.com/v1.0/me/messages', headers=headers,params=params) + if response.status_code == 200: + emails = response.json().get('value', []) + return emails + else: + return None + except Exception as e: + return None + + def _update_refresh_token(self, refresh_token): + """更新refresh_token""" + file_path = os.path.join(self.script_dir, 'email_password.txt') + temp_path = os.path.join(self.script_dir, 'email_password.tmp') + + with self._file_lock: + try: + with open(file_path, 'r') as f, open(temp_path, 'w') as temp: + for line in f: + parts = line.strip().split('----') + if len(parts) == 4 and parts[0] == self.email_data['email']: + parts[3] = refresh_token + line = '----'.join(parts) + '\n' + temp.write(line) + os.replace(temp_path, file_path) + except Exception as e: + print(f"更新refresh_token失败: {e}") + if os.path.exists(temp_path): + os.remove(temp_path) + + def _setup_session(self): + """设置代理会话""" + if not self.proxy_info: + raise ValueError("代理信息为空") + + try: + parts = self.proxy_info.split(":") + if len(parts) != 4: + raise ValueError("代理格式错误") + + proxy_ip, proxy_port, username, password = parts + # 验证端口是否为数字 + if not proxy_port.isdigit(): + raise ValueError("代理端口格式错误") + + proxy_url = f"http://{username}:{password}@{proxy_ip}:{proxy_port}" + self.session = self._session_local.session + self.session.proxies = { + "http": proxy_url, + "https": proxy_url + } + # 设置超时 + self.session.timeout = (10, 30) # 连接超时10秒,读取超时30秒 + except Exception as e: + print(f"设置代理会话失败: {e}") + raise + + def _refresh_steam_info(self): + """刷新Steam信息,获取最新的gid和sitekey""" + try: + # 使用SteamCaptchaHelper获取验证信息 + helper = SteamCaptchaHelper() + steam_data = helper.get_sitekey() + + if not steam_data: + print("获取Steam验证信息失败") + return None + + # 提取数据 + self._steam_init_id = steam_data["init_id"] + self._steam_gid = steam_data["gid"] + self._steam_sitekey = steam_data["sitekey"] + + # 使用SteamCaptchaHelper的session + self.session = steam_data["session"] + + # 输出获取信息 + print(f"获取init_id成功: {self._steam_init_id}") + print(f"获取gid成功: {self._steam_gid}") + print(f"获取sitekey成功: {self._steam_sitekey}") + + # 更新配置中的sitekey + if 'pyno_sitekey' in self.config: + self.config['pyno_sitekey'] = self._steam_sitekey + + # 确保配置中的user_agent与SteamCaptchaHelper一致 + if 'pyno_user_agent' in self.config: + self.config['pyno_user_agent'] = helper.get_user_agent() + + return { + "gid": self._steam_gid, + "sitekey": self._steam_sitekey, + "init_id": self._steam_init_id, + "session": self.session + } + except Exception as e: + print(f"刷新Steam信息出错: {str(e)}") + return None + + def _get_captcha_with_pyno(self): + """使用PyNoCaptcha解决验证码""" + try: + print("正在使用PyNoCaptcha解决验证码...") + + # 先从SteamCaptchaHelper获取标准UA + helper = SteamCaptchaHelper() + standard_user_agent = helper.get_user_agent() + + # 确保sitekey是通过正确的UA获取的 + if not self._steam_sitekey or not self._steam_gid: + print("需要先获取有效的sitekey和gid") + steam_data = helper.get_sitekey() + if steam_data: + self._steam_sitekey = steam_data["sitekey"] + self._steam_gid = steam_data["gid"] + self._steam_init_id = steam_data["init_id"] + self.session = steam_data["session"] + else: + print("无法获取有效的Steam验证信息") + return None + + # 创建PynoCaptcha配置,确保使用正确的UA + config = PynoCaptchaConfig( + user_token=self.config.get('pyno_user_token'), + sitekey=self._steam_sitekey, + referer="https://store.steampowered.com/join/", + user_agent=standard_user_agent, + timeout=self.config.get('pyno_timeout', 60), + debug=self.config.get('pyno_debug', True) + ) + + # 创建求解器 + solver = PynoCaptchaSolver(config) + + # 解决验证码 + print("开始解决验证码...") + result = solver.solve_hcaptcha() + + if not result: + print("PyNoCaptcha验证码解决失败") + return None + + print("PyNoCaptcha验证码解决成功") + return result.get("captcha_text") + + except Exception as e: + print(f"PyNoCaptcha验证码解决出错: {str(e)}") + return None + + def _ajax_verify_email(self): + """发送邮箱验证请求""" + # 使用从SteamCaptchaHelper获取的headers + headers = { + "Host": "store.steampowered.com", + "X-Prototype-Version": "1.7", + "sec-ch-ua-platform": "\"Windows\"", + "sec-ch-ua": "\"Chromium\";v=\"130\", \"Google Chrome\";v=\"130\", \"Not?A_Brand\";v=\"99\"", + "sec-ch-ua-mobile": "?0", + "X-Requested-With": "XMLHttpRequest", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36", + "Accept": "text/javascript, text/html, application/xml, text/xml, */*", + "Content-type": "application/x-www-form-urlencoded; charset=UTF-8", + "Origin": "https://store.steampowered.com", + "Sec-Fetch-Site": "same-origin", + "Sec-Fetch-Mode": "cors", + "Sec-Fetch-Dest": "empty", + "Referer": "https://store.steampowered.com/join/", + "Accept-Language": "zh-CN,zh;q=0.9" + } + + # 更新Cookie + if self.cookie_str: + headers["Cookie"] = self.cookie_str + + print(f"使用gid: {self._steam_gid}") + print(f"使用init_id: {self._steam_init_id}") + + data = { + "email": self.email_data['email'], + "captchagid": self._steam_gid, + "captcha_text": self.token, + "elang": '6', # 使用中文 + "init_id": self._steam_init_id, + "guest": "false" + } + + url = "https://store.steampowered.com/join/ajaxverifyemail" + return self.session.post( + url, + headers=headers, + data=data + ) + + def _generate_random_account_name(self, length): + """生成随机账户名""" + characters = string.ascii_lowercase + string.digits + return ''.join(random.choice(characters) for _ in range(length)) + + def _generate_random_password(self, length): + """生成随机密码""" + characters = string.ascii_letters + string.digits + return ''.join(random.choice(characters) for _ in range(length)) + + def _check_account_name_availability(self, account_name): + """检查账户名可用性""" + payload = { + 'accountname': account_name, + 'count': 1, + 'creationid': self.sessionid + } + + try: + response = self.session.post( + 'https://store.steampowered.com/join/checkavail/', + data=payload, + headers=self.BASE_HEADERS + ) + return response.json() if response.status_code == 200 else None + except Exception as e: + print(f"检查账户名失败: {e}") + return None + + def _check_password_availability(self, account_name, password): + """检查密码可用性""" + payload = { + 'accountname': account_name, + 'password': password, + 'count': 1 + } + + try: + response = self.session.post( + 'https://store.steampowered.com/join/checkpasswordavail/', + data=payload, + headers=self.BASE_HEADERS + ) + return response.json() if response.status_code == 200 else None + except Exception as e: + print(f"检查密码失败: {e}") + return None + + def _save_account(self, account_name, password, success): + """保存账户信息""" + file_name = "accounts_succ.txt" if success else "accounts_fail.txt" + file_path = os.path.join(self.script_dir, file_name) + + with self._file_lock: + try: + with open(file_path, "a", encoding='utf-8') as file: + # 新的固定格式:游戏帐:xxx 游戏密码:xxx 邮箱:xxx 邮箱密码:xxx webmail.evnmail.com + if self.config['protocol'] in ["GRAPH", "IMAP_OAUTH", "POP3_OAUTH"]: + # OAuth版本,包含额外的OAuth信息但不显示在保存的文件中 + save_data = (f"游戏帐:{account_name} 游戏密码:{password} 邮箱:{self.email_data['email']} " + f"邮箱密码:{self.email_data['password']} webmail.evnmail.com\n") + # 额外保存OAuth信息到专门的文件中 + oauth_path = os.path.join(self.script_dir, "accounts_oauth.txt") + with open(oauth_path, "a", encoding='utf-8') as oauth_file: + oauth_file.write(f"{account_name}----{password}----{self.email_data['email']}----" + f"{self.email_data['password']}----{self.email_data['client_id']}----" + f"{self.email_data['refresh_token']}\n") + else: + save_data = (f"游戏帐:{account_name} 游戏密码:{password} 邮箱:{self.email_data['email']} " + f"邮箱密码:{self.email_data['password']} webmail.evnmail.com\n") + file.write(save_data) + except Exception as e: + print(f"保存账户信息失败: {e}") + + def _log_error(self,reason): + self.update_status(f'{reason}',result='线程结束') + """记录错误""" + error_path = os.path.join(self.script_dir, 'rgerror.txt') + with self._file_lock: + try: + with open(error_path, 'a', encoding='utf-8') as file: + # 根据协议类型保存不同格式的错误信息 + if self.config['protocol'] in ["GRAPH", "IMAP_OAUTH", "POP3_OAUTH"]: + # 保存详细的OAuth错误信息到单独文件 + oauth_error_path = os.path.join(self.script_dir, 'oauth_error.txt') + with open(oauth_error_path, 'a', encoding='utf-8') as oauth_file: + oauth_file.write(f"{self.email_data['email']}----{self.email_data['password']}----" + f"{self.email_data['client_id']}----{self.email_data['refresh_token']}\n") + # 主错误文件使用标准格式 + error_data = f"邮箱:{self.email_data['email']} 邮箱密码:{self.email_data['password']} 错误原因:{reason} webmail.evnmail.com\n" + else: + error_data = f"邮箱:{self.email_data['email']} 邮箱密码:{self.email_data['password']} 错误原因:{reason} webmail.evnmail.com\n" + file.write(error_data) + except Exception as e: + print(f"记录错误失败: {e}") + + def _ajax_check_email_verified(self): + """检查邮箱验证状态""" + if not self.sessionid: + return False + + data = {'creationid': self.sessionid} + url = 'https://store.steampowered.com/join/ajaxcheckemailverified' + headers = self.BASE_HEADERS.copy() + headers.update({ + "cookie": self.cookie_str, + }) + + start_time = time.time() + verfy = False + + while True: + if time.time() - start_time > 180: # 超过3分钟退出循环 + self.update_status("邮箱验证超时") + raise Exception("邮箱验证超时") + response = self.session.post(url, data=data, headers=headers) + if response.ok: + success = response.json() + if success['success'] == 1 or verfy: + # 处理账户创建 + self.update_status("邮箱验证完成,提交注册") + return self._create_account() + else: + print('等待邮箱验证') + self.update_status("等待邮箱验证") + if self._fetch_email_verification_url(): + time.sleep(5) + verfy = True + time.sleep(2) + else: + time.sleep(5) + + def _fetch_email_verification_url(self): + """获取邮箱验证链接""" + max_attempts = 6 + attempts = 0 + href = '' + urls = [] + + def extract_urls_from_body(body, pattern): + found_urls = re.findall(pattern, body) + return [url.replace('&', '&').replace("=3D", "=").replace("=\r\n", "") + .replace("\r\n", "").replace("=\n", "").replace("\n", "") + for url in found_urls] + + def decode_mime_words(text): + """解码MIME编码的文本""" + if not text: + return "" + try: + decoded = email.header.decode_header(text) + return " ".join([ + (str(t[0], t[1] or 'utf-8') if isinstance(t[0], bytes) else str(t[0])) + for t in decoded + ]) + except: + return text + + def get_body_text(msg): + """获取邮件正文文本内容""" + if msg.is_multipart(): + # 如果邮件包含多个部分,递归处理 + text_parts = [] + for part in msg.get_payload(): + if part.get_content_type() == 'text/plain': + charset = part.get_content_charset() or 'utf-8' + try: + text_parts.append(part.get_payload(decode=True).decode(charset)) + except: + text_parts.append("[无法解码的内容]") + elif part.is_multipart(): + # 递归处理多部分 + text_parts.append(get_body_text(part)) + return "\n".join(text_parts) + else: + # 单部分邮件 + content_type = msg.get_content_type() + if content_type == 'text/plain': + charset = msg.get_content_charset() or 'utf-8' + try: + return msg.get_payload(decode=True).decode(charset) + except: + return "[无法解码的内容]" + else: + return f"[内容类型: {content_type}]" + + def process_emails(emails, pattern): + for email in emails: + body = email.get('body', {}).get('content', '') + urls.extend(extract_urls_from_body(body, pattern)) + + def fetch_imap_emails(): + """获取IMAP邮件中的验证链接""" + local_urls = [] + try: + self.update_status("正在连接IMAP服务器...") + # 连接到IMAP服务器 + if self.config['ssl']: + mail = imaplib.IMAP4_SSL(self.config['email_url']) + else: + mail = imaplib.IMAP4(self.config['email_url']) + + # 登录 + self.update_status(f"正在登录邮箱...") + mail.login(self.email_data['email'], self.email_data['password']) + self.update_status("登录成功,开始获取邮件...") + + # 只检查INBOX文件夹 + steam_verification_pattern = r'https://store\.steampowered\.com/account/newaccountverification\?[^\s"\'<>]+' + + try: + self.update_status("检查收件箱...") + mail.select("INBOX") + status, messages = mail.search(None, "ALL") + if status != "OK" or not messages[0]: + self.update_status("收件箱为空或无法访问") + else: + # 获取邮件ID列表,从最新的开始 + message_ids = messages[0].split() + message_count = len(message_ids) + self.update_status(f"找到 {message_count} 封邮件") + + # 最多检查5封最新邮件 + check_count = min(5, message_count) + message_ids = message_ids[-check_count:] + message_ids.reverse() # 最新的邮件放在前面 + + for i, msg_id in enumerate(message_ids): + self.update_status(f"正在检查邮件 {i+1}/{check_count}...") + status, msg_data = mail.fetch(msg_id, "(RFC822)") + if status != "OK": + continue + + # 解析邮件内容 + raw_email = msg_data[0][1] + msg = email.message_from_bytes(raw_email, policy=default) + + # 提取信息 + subject = decode_mime_words(msg["Subject"]) + + # 如果是Steam邮件,优先处理 + if "Steam" in subject: + self.update_status(f"找到Steam邮件: {subject}") + # 获取正文 + body = get_body_text(msg) + + # 查找Steam验证链接 + found_urls = extract_urls_from_body(body, steam_verification_pattern) + if found_urls: + self.update_status(f"发现 {len(found_urls)} 个Steam验证链接") + local_urls.extend(found_urls) + else: + self.update_status("不是Steam邮件,跳过") + except Exception as e: + self.update_status(f"处理邮件出错: {str(e)}") + + # 尝试关闭连接 + try: + mail.close() + except: + pass + mail.logout() + + except Exception as e: + self.update_status(f"IMAP连接失败: {str(e)}") + + return local_urls + + def process_pop3(mail, pattern): + num_messages = len(mail.list()[1]) + for i in range(num_messages): + raw_email = b'\n'.join(mail.retr(i + 1)[1]) + text_body = raw_email.decode("utf-8") + urls.extend(extract_urls_from_body(text_body, pattern)) + + while attempts < max_attempts: + try: + if self.config['protocol'] == "GRAPH": + emails = self._graph_get_email() + if emails: + process_emails(emails, r'href="(https://store\.steampowered\.com/account/newaccountverification\?[^"]+)"') + else: + if self.config['protocol'] in ["IMAP", "IMAP_OAUTH"]: + if self.config['protocol'] == "IMAP_OAUTH": + self._get_access_token() + if not self.access_token: + attempts += 1 + time.sleep(5) + continue + mail = self._authenticate_oauth2() + else: + # 使用改进的IMAP处理 + self.update_status("开始获取邮件...") + imap_urls = fetch_imap_emails() + urls.extend(imap_urls) + + elif self.config['protocol'] in ["POP3", "POP3_OAUTH"]: + if self.config['protocol'] == "POP3_OAUTH": + self._get_access_token() + if not self.access_token: + attempts += 1 + time.sleep(5) + continue + mail = self._authenticate_oauth2() + else: + mail = poplib.POP3_SSL(self.config['email_url']) if self.config['ssl'] else poplib.POP3(self.config['email_url']) + mail.user(self.email_data['email']) + mail.pass_(self.email_data['password']) + process_pop3(mail, r'https://store\.steampowered\.com/account/newaccountverification\?stoken=3D[^\n]*\n[^\n]*\n[^\n]*\n\n\n') + mail.quit() + + # 检查验证链接 + for url in urls: + self.update_status(f"找到可能的验证链接,检查匹配...") + parsed_url = urlparse(url) + query_string = parsed_url.query + params = parse_qs(query_string) + creationid = params.get('creationid') + if creationid and creationid[0] == self.sessionid: + href = url + break + + if href: + self.update_status("找到匹配的验证链接,正在验证...") + return self._verify_email_link(href) + else: + self.update_status("未找到匹配的验证链接,等待5秒后重试...") + attempts += 1 + time.sleep(5) + + except Exception as e: + self.update_status(f"邮件处理错误: {str(e)}") + attempts += 1 + time.sleep(5) + + if attempts >= max_attempts: + self.update_status("达到最大尝试次数,未能成功获取邮件或链接") + return False + + def _verify_email_link(self, href): + """验证邮箱链接""" + headers = self.BASE_HEADERS.copy() + headers.update({ + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", + "Upgrade-Insecure-Requests": "1" + }) + try: + response = self.session.get(href, headers=headers) + soup = BeautifulSoup(response.content, "html.parser") + error_div = soup.find("div", class_="newaccount_email_verified_text error") + + if error_div: + print('验证失败') + return False + print("验证完成") + return True + except Exception as e: + print(f"验证链接访问失败: {e}") + return False + + def _create_account(self): + """创建Steam账户""" + # 生成随机账户名和密码 + account_name = self._generate_random_account_name(random.randint(8, 12)) + + # 检查账户名可用性 + result = self._check_account_name_availability(account_name) + if result: + if result['bAvailable']: + print(f"账户名可用: {account_name}") + else: + print("账户名不可用") + if 'rgSuggestions' in result and result['rgSuggestions']: + print("使用建议的账户名:", result['rgSuggestions'][0]) + account_name = result['rgSuggestions'][0] + else: + raise Exception("无法获取可用的账户名") + else: + raise Exception("账户名检查失败") + + # 生成并检查密码 + while True: + password = self._generate_random_password(random.randint(8, 12)) + password_result = self._check_password_availability(account_name, password) + if password_result and password_result['bAvailable']: + print(f"密码可用: {password}") + break + print("密码不可用,重新生成") + + # 创建账户 + self.update_status("创建账户",account_name=account_name,password=password) + self._create_steam_account(account_name, password) + return True + + def _create_steam_account(self, account_name, password): + """提交Steam账户创建请求""" + data = { + 'accountname': account_name, + 'password': password, + 'count': 0, + 'lt': 1, + 'creation_sessionid': self.sessionid, + 'embedded_appid': 0, + 'guest': False + } + headers = self.BASE_HEADERS.copy() + headers.update({ + "Cookie": self.cookie_str, + "X-Requested-With": "XMLHttpRequest" + }) + try: + response = self.session.post( + 'https://store.steampowered.com/join/createaccount/', + data=data, + headers=headers + ) + if response.ok: + result = response.json() + print(f'{account_name} 提交注册完成') + self.update_status('提交注册完成',account_name=account_name,password=password,result=result['bSuccess']) + self._save_account(account_name, password, result['bSuccess']) + else: + raise Exception(f'创建账户请求失败: {response.status_code}') + except Exception as e: + print(f'创建账户时出错: {str(e)}') + raise + + def main(self, email_data, retries=30): + """主处理函数""" + main_retry_count = 0 + self.email_data = email_data + if not self.is_email_valid(): + self._log_error("邮箱验证失败") + return + while main_retry_count < retries: + try: + if not self.running: + self.update_status("任务已停止") + break + + # 设置代理(其他功能仍然需要代理) + self.proxy_info = self.proxy_pool.get_proxy() + self._setup_session() + + # 先使用SteamCaptchaHelper获取验证信息,它使用正确的User-Agent + self.update_status("获取Steam验证信息") + helper = SteamCaptchaHelper() + + # 如果有代理,设置到helper的session + if hasattr(self.session, 'proxies') and self.session.proxies: + helper.session.proxies = self.session.proxies + + steam_data = helper.get_sitekey() + if not steam_data: + self.update_status("获取Steam验证信息失败,重试") + raise Exception("获取Steam验证信息失败") + + # 提取并保存验证信息 + self._steam_init_id = steam_data["init_id"] + self._steam_gid = steam_data["gid"] + self._steam_sitekey = steam_data["sitekey"] + + # 使用helper的session + self.session = steam_data["session"] + + # 设置cookie + self.cookie_str = "timezoneOffset=28800,0; Steam_Language=english; " + cookies = self.session.cookies.get_dict() + if cookies: + self.cookie_str += '; '.join([f"{k}={v}" for k, v in cookies.items()]) + + # 使用PyNoCaptcha解决验证码 + self.update_status("使用PyNoCaptcha进行人机验证") + self.token = self._get_captcha_with_pyno() + if not self.token: + self.update_status("验证码解决失败,重试") + raise Exception("验证码解决失败") + self.update_status("验证码解决成功") + + # 提交邮箱验证 + self.update_status("提交注册验证") + response = self._ajax_verify_email() + + # 处理响应 + try: + resp_json = response.json() + success = resp_json.get('success', 0) + details = resp_json.get('details', '') + self.update_status(f'提交结果:状态={success}, 详情={details}') + + if success != 1: + self.update_status(f"验证未通过: {details}", result="失败") + raise Exception(f"验证未通过: {details}") + + # 获取sessionid + self.sessionid = resp_json.get('sessionid') + if not self.sessionid: + self.update_status("未能获取sessionid", result="失败") + raise Exception("未能获取sessionid") + + # 进行邮箱验证 + self.update_status("等待邮箱验证") + self._ajax_check_email_verified() + + # 成功完成 + self.session.close() + self.proxy_pool.mark_success(self.proxy_info) + self.proxy_info = None + break + + except Exception as e: + self.update_status(f"处理响应出错: {str(e)}") + raise + + except Exception as e: + if not self.running: + self.update_status("任务已停止") + break + + # 安全地打印错误,避免泄露敏感信息 + error_msg = str(e) + if len(error_msg) > 50: + error_msg = error_msg[:50] + "..." + self.update_status(f"出错: {error_msg}") + + # 清理资源 + if self.session: + try: + self.session.close() + except: + pass + if self.proxy_info: + self.proxy_pool.mark_fail(self.proxy_info) + self.proxy_info = None + + # 增加重试计数 + main_retry_count += 1 + time.sleep(2) + + # 达到最大重试次数 + if main_retry_count >= retries: + self._log_error("达到最大重试次数") + finally: + # 确保资源被释放 + if self.session: + try: + self.session.close() + except: + pass + if self.proxy_info: + self.proxy_pool.mark_fail(self.proxy_info) + self.proxy_info = None \ No newline at end of file diff --git a/ThreadManagerWithPyno.py b/ThreadManagerWithPyno.py new file mode 100644 index 0000000..48ae094 --- /dev/null +++ b/ThreadManagerWithPyno.py @@ -0,0 +1,155 @@ +from concurrent.futures import ThreadPoolExecutor +import json +import os +import threading +from ProxyPool import ProxyPool +from SteamRegistrationWithPyno import SteamRegistrationWithPyno + + +class ThreadManagerWithPyno: + """线程管理器 - 使用PyNoCaptcha版本""" + def __init__(self, config_path, email_file_path, proxy_file_path): + self.config = self._load_config(config_path) + self._validate_config() + self.proxy_pool = ProxyPool(proxy_file_path) + self.email_file = email_file_path + self.executor = ThreadPoolExecutor(max_workers=self.config['executornum']) + self._registration_local = threading.local() + self._running = True + self._registrations = set() + self._registrations_lock = threading.Lock() + + def _validate_config(self): + """验证配置有效性""" + required_fields = ['protocol', 'ssl', 'email_url', 'executornum', 'pyno_user_token'] + for field in required_fields: + if field not in self.config: + raise ValueError(f"配置缺少必要字段: {field}") + + def _load_config(self, config_path): + """加载配置""" + with open(config_path, 'r') as f: + return json.load(f) + + def parse_email_credentials(self, line): + """解析邮件凭据""" + parts = line.strip().split("----") + if len(parts) == 2: + return { + 'email': parts[0], + 'password': parts[1] + } + elif len(parts) == 4: + return { + 'email': parts[0], + 'password': parts[1], + 'client_id': parts[2], + 'refresh_token': parts[3] + } + raise ValueError("Invalid email credentials format") + + def _get_registration(self): + """获取线程本地的SteamRegistrationWithPyno实例""" + if not hasattr(self._registration_local, 'registration'): + registration = SteamRegistrationWithPyno( + self.config, + self.proxy_pool, + ) + self._registration_local.registration = registration + # 将新创建的实例添加到跟踪集合 + with self._registrations_lock: + self._registrations.add(registration) + return self._registration_local.registration + + def process_email(self, email_data): + registration = self._get_registration() + registration.main(email_data) + + + def stop(self): + """停止所有任务""" + self._running = False + # 首先关闭线程池,不再接受新任务 + self.executor.shutdown(wait=False) + + # 遍历并停止所有注册实例 + with self._registrations_lock: + for registration in self._registrations: + try: + registration.running = False + if (hasattr(registration, 'session') and + registration.session and + not getattr(registration.session, 'closed', True)): + # 只有当session存在且未关闭时才进行关闭 + registration.session.close() + except Exception as e: + pass + + # 清空实例集合 + self._registrations.clear() + + def start(self): + """启动处理""" + self._running = True + try: + with open(self.email_file, "r") as file: + for line in file: + if not self._running: + break + try: + email_data = self.parse_email_credentials(line.strip()) + self.executor.submit(self.process_email, email_data) + except ValueError as e: + print(f"错误的邮箱格式: {e}") + continue + finally: + self.executor.shutdown(wait=True) + +class GUIThreadManagerWithPyno(ThreadManagerWithPyno): + def __init__(self, config_path, email_file_path, proxy_file_path, gui, completed_tasks=None): + super().__init__(config_path, email_file_path, proxy_file_path) + self.gui = gui + self.completed_tasks = completed_tasks or set() + + def process_email(self, email_data): + """处理单个邮件账号""" + try: + if not self._running: # 检查是否应该继续 + self.gui.update_status(email_data['email'], "任务已停止") + return + + # 先更新状态为"准备中" + self.gui.update_status(email_data['email'], "准备验证邮箱...") + + # 获取注册实例 + registration = self._get_registration() + registration.set_gui(self.gui) # 设置GUI引用 + registration.running = self._running + + # 开始处理 + self.gui.update_status(email_data['email'], "开始验证邮箱") + registration.main(email_data) + + except Exception as e: + # 捕获所有异常并更新状态 + error_msg = str(e) + # 确保错误信息不包含敏感数据 + if len(error_msg) > 100: + error_msg = error_msg[:100] + "..." + self.gui.update_status(email_data['email'], f"处理失败: {error_msg}", result="失败") + + def start(self): + """启动处理""" + self._running = True + with open(self.email_file, 'r', encoding='utf-8') as file: + with ThreadPoolExecutor(max_workers=self.config['executornum']) as self.executor: + for line in file: + if not self._running: + break + try: + email_data = self.parse_email_credentials(line) + # 跳过已完成的任务 + if email_data['email'] not in self.completed_tasks: + self.executor.submit(self.process_email, email_data) + except ValueError as e: + self.gui.update_status(email_data['email'],f"解析邮箱文件失败: {e}") \ No newline at end of file diff --git a/__pycache__/ProxyPool.cpython-312.pyc b/__pycache__/ProxyPool.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..536b1a23a6e277e38ecce260af421066c3c18636 GIT binary patch literal 3508 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 literal 0 HcmV?d00001 diff --git a/__pycache__/RegistrationGUIWithPynoV2.cpython-312.pyc b/__pycache__/RegistrationGUIWithPynoV2.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9648e6bb58ddc8410fd5c0d5e46cce3d898abda1 GIT binary patch literal 31178 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 literal 0 HcmV?d00001 diff --git a/__pycache__/SteamCaptchaHelper.cpython-312.pyc b/__pycache__/SteamCaptchaHelper.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71ee822bdad89418a7fd6f660a2e288302cc9478 GIT binary patch literal 5081 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�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 literal 0 HcmV?d00001 diff --git a/accounts_succ.txt b/accounts_succ.txt new file mode 100644 index 0000000..d4f77cc --- /dev/null +++ b/accounts_succ.txt @@ -0,0 +1 @@ +ejd71m5tr----z1xG24ZXbHp----5ulxb79e@evnmail.com----dr!mueh15ahG diff --git a/config.json b/config.json new file mode 100644 index 0000000..d0c5869 --- /dev/null +++ b/config.json @@ -0,0 +1,12 @@ +{ + "protocol": "IMAP", + "ssl": true, + "email_url": "mail.evnmail.com", + "executornum": 1, + "pyno_user_token": "cf169d36-0d62-45da-bff7-1eff42bbc4f3", + "pyno_sitekey": "eb9cbe72-814a-4392-b9b2-f8965f3686ee", + "pyno_referer": "https://store.steampowered.com/join/", + "pyno_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36", + "pyno_timeout": 60, + "pyno_debug": true +} \ No newline at end of file diff --git a/email_password.txt b/email_password.txt new file mode 100644 index 0000000..eb3fd56 --- /dev/null +++ b/email_password.txt @@ -0,0 +1 @@ +5ulxb79e@evnmail.com----dr!mueh15ahG \ No newline at end of file diff --git a/proxy_ips.txt b/proxy_ips.txt new file mode 100644 index 0000000..5314942 --- /dev/null +++ b/proxy_ips.txt @@ -0,0 +1 @@ +gw.dataimpulse.com:823:3b9936d2ce39b35c4bdf:2263006e0ff05530 \ No newline at end of file diff --git a/rgerror.txt b/rgerror.txt new file mode 100644 index 0000000..475fbe0 --- /dev/null +++ b/rgerror.txt @@ -0,0 +1 @@ +5ulxb79e@evnmail.com----dr!mueh15ahG diff --git a/start_pyno_v3.py b/start_pyno_v3.py new file mode 100644 index 0000000..f7ef8c0 --- /dev/null +++ b/start_pyno_v3.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Steam注册程序 - PyNoCaptcha V3版本启动器 +使用PyNoCaptcha解决验证码,解决了sitekey获取问题 +""" + +import tkinter as tk +from RegistrationGUIWithPynoV2 import RegistrationGUIWithPynoV2 + +if __name__ == "__main__": + print("正在启动Steam注册助手 PyNoCaptcha V3版本...") + print("这个版本修复了验证码头信息问题,使用正确的User-Agent获取sitekey") + root = tk.Tk() + gui = RegistrationGUIWithPynoV2(root) + root.mainloop() \ No newline at end of file diff --git a/steam_registration_pyno.log b/steam_registration_pyno.log new file mode 100644 index 0000000..fd7da16 --- /dev/null +++ b/steam_registration_pyno.log @@ -0,0 +1,179 @@ +2025-05-22 18:05:35.258 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:05:35.916 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 17593453638535276028 +2025-05-22 18:05:35.917 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 18:05:36.296 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 4052156986341176 +2025-05-22 18:05:36.299 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:05:36.325 | DEBUG | PynoCaptchaSolver:__init__:21 - PynoCaptchaSolver 初始化 - 使用 PyNoCaptcha 库 +2025-05-22 18:05:36.341 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:31 - 开始解决验证码 - sitekey: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:05:36.343 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:32 - 使用User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36 +2025-05-22 18:05:36.346 | DEBUG | pynocaptcha.crackers.base:__init__:58 - 感谢选择 nocaptcha, 我们只做别人做不到的(手动狗头)~ +2025-05-22 18:05:36.347 | DEBUG | pynocaptcha.crackers.base:__init__:59 - 欢迎推荐注册, 官网地址: https://www.nocaptcha.io/ +2025-05-22 18:05:36.348 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:45 - 调用 PyNoCaptcha 进行破解 +2025-05-22 18:05:43.925 | INFO | pynocaptcha.crackers.base:crack:153 - {'status': 1, 'msg': '验证成功', 'id': 'cfffdb69-6885-49be-a5f5-e16d5286fbe9', 'cost': '6834.29ms', 'data': {'generated_pass_UUID': 'P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.hadwYXNza2V5xQOltp3ltqiset16UHk24wluUI5MNqjTWl-pg6bi80iT3MO-LpDJyN4rmCDjo7XFO7wlE3mr3HTmp3H7BNvBg4XgpORGD7Jd6Bua7y_TfT2qNFNp-l2zH98ywODwZaGp-BvvdgplW7UQvgtn95vvYDrrVBQHI6a9W6pFP1rKj0KZj2vxATmuNbVBg5qAywUJF57-HfuqUIAFmXA4oPnpnHbBWwefkpLFnZCf2ZQ_bZBC2Xn91SFVSUSS8aMW0g68u5lqYawAxUeIibhaL6ZqIPTx9jFKkQqBQvF4x0NDK_HERoVkwuxZRw3aKc6msbB-Ibrbyu9IhiyAT_I08LADsj9VOtQnJge1cRJ9MhEwsxWmZy-Zcxg9q6B9W7Gqg2af8CxyyT4Uc-tLzev9wmr27D1_ugGL0rUEgj6r3x7EZtdqjwjKRwaprrM2w89iNanUWTaAWiVCXc1dDa0YpOwrNfqMbdM6WFQXOsohqwQP48ippYAa7ARWkD2sI4IwmR9W8u3Njj1qKhQ9uV3fK_05cI4sojvWKKiNuajTXgtvBUuh7Ev4-342tR0mbfzJ4cn2XekmrNHw_42lJ7pCWh0ZJSi-Iz8xsQ_brxUSE0lEuLvxRhWspgYd0afUMicd2EY38GBy-NEgmRONGQS0eK9rnuY_-jCuYm8RY6m490I7KfzpifnfCylq-VGeQ1qtrgW5CVXZYtuoCjmxKMCgMSbjPipvfrUFsaza6JLrbeeVZLqlFsZbUWXhpfXykEPM3fsgXWlMH4OA7yTrPEW6h5ym8FB0s8ihY5nWnc7yT56KIYCf991EBXm7FpNP3ijYGae9yFys8lgcx30T27e-OBt8amIXhJNo80iytijDD_QWh4PbhsRh7Ztw08JjBfKvGAUP5sebu8zI5YK7udTSmJFv9ee1CyxbjXx90j4VVJMOSjkdUbo9JJfodE6_r7ve2J-t9hSWs_ylWbSaB1bF59q7hrlI_S4vKWNtd2CQpKsIBSkk5lm4HVpe6XNi6ncS7z5LOZGFqMcuEQTEd0krjp84F1Gi7tq9SOIxGuAgtZC2p1s8pW9p34xY979-40zUxJPsqasHNtpcwNtszwKwwUO4mOMoRtji9ZnTe_fnefvcTudDHlr82XsGVmGvYrsWvPB1P_OUCSj212IGu_FJGP9-8B5cGvsIgmNlwd2Drolrw-feaduS8RG03EfPWHccCg3wJ_5xjIhVFrqgaPZCu-FfKXCABJXgWi7io2V4cM5oLvdvqHNoYXJkX2lkzg9y6m-ia3KoMWNmODU4ODKicGQA.0PCJXfyqO4HUbOQWBOjYW9JP2mBPzHH5OS2FnR4lBTw', 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1745876290) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36'}, 'extra': {}, 'en_msg': 'Verify success'} +2025-05-22 18:05:43.927 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:49 - 验证码破解成功 +2025-05-22 18:05:43.961 | INFO | SteamCaptchaHelper:verify_email:72 - 验证邮箱: 749army@gmail.com +2025-05-22 18:05:44.411 | INFO | SteamCaptchaHelper:verify_email:87 - 验证邮箱结果: {'success': 1, 'sessionid': '3145536910878670205', 'details': ''} +2025-05-22 18:05:59.312 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:05:59.661 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 232517025202945862 +2025-05-22 18:05:59.662 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 18:05:59.975 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 4052156986341532 +2025-05-22 18:05:59.977 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:06:01.071 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:01.597 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:03.644 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:04.129 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:06.206 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:06.670 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:08.719 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:09.190 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:11.276 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:11.743 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:13.787 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:14.265 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:16.317 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:16.794 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:18.841 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:19.305 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:22.443 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:22.926 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:28.298 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:28.789 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:34.104 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:34.579 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:39.936 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:40.392 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:45.655 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:46.269 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:51.679 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:52.140 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:06:57.405 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:06:57.880 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:03.151 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:03.645 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:08.911 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:09.372 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:14.648 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:15.114 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:20.404 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:20.865 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:26.140 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:26.608 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:31.877 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:32.377 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:37.651 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:38.116 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:43.399 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:43.936 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:49.217 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:49.730 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:07:54.997 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:07:55.523 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:00.784 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:01.378 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:06.645 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:06.950 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:12.235 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:12.590 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:12.710 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:13.450 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 17683348673253827567 +2025-05-22 18:08:13.452 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 18:08:13.765 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 4052156986343432 +2025-05-22 18:08:13.766 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:08:14.817 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:15.275 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:17.310 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:17.780 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:17.982 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:18.459 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:19.817 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:20.286 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:22.324 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:22.811 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:23.838 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:24.296 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:24.850 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:25.326 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:27.369 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:27.843 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:29.888 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:30.366 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:32.398 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:32.702 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:34.734 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:35.205 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:37.245 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:37.710 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:39.743 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:40.223 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:42.267 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:42.579 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:44.615 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:45.075 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:47.120 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:47.427 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:49.463 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:49.942 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:51.986 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:52.457 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:54.497 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:54.962 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:56.990 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:57.299 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:08:59.349 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:08:59.838 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:09:01.899 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:09:02.475 | ERROR | SteamCaptchaHelper:get_sitekey:66 - 获取sitekey过程中出错: HTTPSConnectionPool(host='store.steampowered.com', port=443): Max retries exceeded with url: /join/ (Caused by ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 403 Forbidden'))) +2025-05-22 18:28:03.451 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:28:04.042 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 12411724988176453952 +2025-05-22 18:28:04.045 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 18:28:04.374 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 4052156986360263 +2025-05-22 18:28:04.375 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:28:05.423 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 18:28:08.085 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 9685715838321349259 +2025-05-22 18:28:08.087 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 18:28:08.785 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 5178056896388019 +2025-05-22 18:28:08.787 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:28:08.804 | DEBUG | PynoCaptchaSolver:__init__:21 - PynoCaptchaSolver 初始化 - 使用 PyNoCaptcha 库 +2025-05-22 18:28:08.806 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:31 - 开始解决验证码 - sitekey: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 18:28:08.807 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:32 - 使用User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36 +2025-05-22 18:28:08.808 | DEBUG | pynocaptcha.crackers.base:__init__:58 - 感谢选择 nocaptcha, 我们只做别人做不到的(手动狗头)~ +2025-05-22 18:28:08.809 | DEBUG | pynocaptcha.crackers.base:__init__:59 - 欢迎推荐注册, 官网地址: https://www.nocaptcha.io/ +2025-05-22 18:28:08.810 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:45 - 调用 PyNoCaptcha 进行破解 +2025-05-22 18:28:15.693 | INFO | pynocaptcha.crackers.base:crack:153 - {'status': 1, 'msg': '验证成功', 'id': '6c04790c-1097-410b-adf1-a5d2240a000f', 'cost': '6150.71ms', 'data': {'generated_pass_UUID': 'P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.hadwYXNza2V5xQOlK8mkTImlsBoatBxSNYDqDmJIB7oihj5M9YTIa0epQU7HVi4rr027uynB6YXihE-n4k0gt-GUcxs9viLCZeaLVycviwe4h9QHgjeubbIDIvfeNMp_bbU1xOXuxrL1UN_6OSktEFgfPEaambWm4v7s6jCjv0TwXFepzS4CmlBmMf1T3xB_nNburK51zkiRVV1d_UTyvx4gEoSlLapJJ5vZM-k8F1NvWZG0vA_K4m4XsLSt8Vz2Uy5TLPp8mpM3imHAm3zVY2Bk5rsKyNhDUs71S3ct3OrQFhly8P2motuPecviMQOqxXRqCAki8icYn70LBAQM2yQ6UYwgu5pd5UWKrheFX995N0k_RzarWIs-ShddEwzzy6T62lZUjWvJqa16sQSpjQU8w1FJ2MDcz6L54Zct_09uYCEvwwkOfjRc2LAJNv_QaOHokO3coWNW1W7-zSro40bAcbKGxC3z0WQJhbdb5rrO5a1wlIyGi62AQceoCkMuMWtFuuarUQjPHWaLc5ux8z5pzmUXr-k487rMmRsx7TbF6mD5w2bCopa_-aYCKktUgE3teWMmDNHN7c3-n5B_t0kPX5XP9_eNoSK6Ud1CvX7aYwtFyX0oerLc9r_yNMRVJHkg8KXuPxWs9fJCEQO4ARAcsTE9hLhgdPXsR6X2RVBHmn2q62amK1bFmGIkRuSYTUtOhQWHKsIyHKa6YAElDf5vhjHuoU2UzUC5QZPijesdIpHZdt24S_AU4Nwi8RIY3VDAakKR0hpcftmc5-4DKkgLx91V5oj-Hzef5AD8vVAcEsTgjDT33gsez30aDz-qXpuzk2nHqo9BgIBVy63l7lkXhUa3v-q83jqmw4NTBG3ckpRv4KeKioiYJDKm7WPrjkQ4bdXXc36eDXvafT84DuEC1B82SyxqjVydYxySxjjncbW26tRsdltIffv5TCpAJ5gJI0KHLRE4xfYAAWcCpxDU6ZIA52zX6JdyhskCb9smBWGC0eFKAGxAM6i2-atjvGknnkSU-L6kwM7DpvxgtO-iDl7GMC2xfLAvzGbQmGzTTSGtXbDIXRQjF-xw3yieKMOLbpD5KYSjtAiH_2D0qouAMCdtTQXIhup7acrAnlB5Q4HYEiqCjIJGg_lXkcMCKvIMUWlveZUCKMtfkw0PyBveWOSSvkPbD694rrykXYkzl0IObB1SMEWNrrl5mFE7RDhqWhFF7JSj_ELUWXjKL10Jd3ekOqA48FyD7IAGOKfgo2V4cM5oLvy3qHNoYXJkX2lkzg9y6m-ia3KoMjhlOTQ4N2GicGQA.sOwvAIUlF5NO2AMxXECfDVfKi7EKAJtV-HH7uhyQu_I', 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1745876290) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36'}, 'extra': {}, 'en_msg': 'Verify success'} +2025-05-22 18:28:15.695 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:49 - 验证码破解成功 +2025-05-22 20:27:29.115 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 20:27:29.784 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 1862677362228322809 +2025-05-22 20:27:29.785 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 20:27:30.124 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 4052156986473234 +2025-05-22 20:27:30.125 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 20:27:31.283 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 20:27:33.570 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 18091961620671672591 +2025-05-22 20:27:33.572 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 20:27:34.358 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 11933456348020478 +2025-05-22 20:27:34.360 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 20:27:34.372 | DEBUG | PynoCaptchaSolver:__init__:21 - PynoCaptchaSolver 初始化 - 使用 PyNoCaptcha 库 +2025-05-22 20:27:34.374 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:31 - 开始解决验证码 - sitekey: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 20:27:34.375 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:32 - 使用User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36 +2025-05-22 20:27:34.376 | DEBUG | pynocaptcha.crackers.base:__init__:58 - 感谢选择 nocaptcha, 我们只做别人做不到的(手动狗头)~ +2025-05-22 20:27:34.376 | DEBUG | pynocaptcha.crackers.base:__init__:59 - 欢迎推荐注册, 官网地址: https://www.nocaptcha.io/ +2025-05-22 20:27:34.377 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:45 - 调用 PyNoCaptcha 进行破解 +2025-05-22 20:27:42.545 | INFO | pynocaptcha.crackers.base:crack:153 - {'status': 1, 'msg': '验证成功', 'id': '68d5df40-ef27-4d3c-b202-9b549d5597c8', 'cost': '7378.42ms', 'data': {'generated_pass_UUID': 'P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.hadwYXNza2V5xQOg7-sqzaJIrXnmUqggD_D9N_zjuUd7g9V4cSaQJn2yNLx1jcL0IQw1CIQsuxv8j3zLtxeRqH_B0piqcJoR3QrgQfTIIaNPi8aE2l4TXyQsVZRqBf9aouKMBdbZ5cdSM7MBLCPh7ZWXImfu34xRkONTXrx_9wpm6m2TfIyXkHBlmQCCF-iHjkJAKQtdghuXfSZTXBzc2IG2bdFZFRemfJTgPZpdPvjP3RaD-TjwbIdRU1yrDxQDrUO2W7Saax8qc7huwfGIVl__iTYS7ZPL8PuHBNXX2NGLbuVJw2oltOcr0rP6y2Fb2JaU6mewyuixeGRMGL2zDiC0OjSzg6KSwdr5-7L8ueiPnA_NT8oIF_PoFi4O9IOatx6gCxNevgJjM4a9zBOOchjXgXIRZ3CbmLckAPzU9njcsoM5SIg1lrMXPASk4aoI2D0xgNZ5-2crAHW9Hn8u8sIukWWH3bcoQdNZ2XFvITbXf5YjyHVHQDvcym4r-VMffmsqD4qWEfZT5_kGITbpHLjC3Zk9_UuDLaPyEyqkIvmyhlfTY77P4EcILLlnV6QGZ7Jp6NpXvbw1hiK-CLSLluYf7iN1PK079TUkTsHVBkUG3LakJBAQfY1FIgb6zScPvd51oyc5HIAjVXf_0DDaQSl71IaP6vPAGdez0Tl2bSzmio8y0YZv-nmGTVL5hpVPlDz--UAeyAoYF2b986xpySCPn9fOm_ftCVST6yVbYRPrv6UAC-ya0y1RwXtsKP5iB8ZsYT5t2vn1K8MypVCwCwhK7bZsBqBTawkcSKgOmKt-Bk_uYAt6gJJeuPM_jwGoiMqLIqfH61qavl49NicpbS3XmuA10xTnhf-5hsV5yT1GYvWAN7pAfyftpoLZU6w3KWwV3bZpkd7Y_6KMkbHXDs-dPXUQyD2TmMS-o-TCiXJSJTgPQ3O-GWCCnmJa62RYSkd07FoWTO4t1-2qHuzMntwEwElvCl5sNcybLymA71iFyxia22Kj0MbdMXSa6ZfE7BQTfgNzRLlClrT8myvFodN4fqJ7l6IiBLMZLAF2LmSWRFoqlZfJsSd5UM_nhhbNqAt-n7EyZ9naPU0JFcd5HrdodIAMJzz_EM5cNRkIJLID4TyHjG591l9JP6WBy0MRHz4bGYa_R2b7DHVG__-H0H-JyPX5txSa0gA4zGPhmUq0MyPc4O46iMbCPVW1ZGJq_52XBTmDsIu7CabmfBa4jsz4uugzfGP8AWuFrqNleHDOaC8YtqhzaGFyZF9pZM4xrUyBomtyqDE2ZDQ1YTU3onBkAA.tfSoMC6piw9EwluZobqrWQgblQupX6ruwU3Y2HZnA48', 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1745876290) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36'}, 'extra': {}, 'en_msg': 'Verify success'} +2025-05-22 20:27:42.548 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:49 - 验证码破解成功 +2025-05-22 20:32:30.378 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 20:32:31.108 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 1027762256794772261 +2025-05-22 20:32:31.109 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 20:32:31.466 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 4052156986478325 +2025-05-22 20:32:31.467 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 20:32:32.540 | INFO | SteamCaptchaHelper:get_sitekey:32 - 获取Steam注册页面... +2025-05-22 20:32:34.746 | INFO | SteamCaptchaHelper:get_sitekey:41 - 获取init_id成功: 8413603079758422192 +2025-05-22 20:32:34.748 | INFO | SteamCaptchaHelper:get_sitekey:47 - 刷新验证码获取sitekey... +2025-05-22 20:32:35.412 | INFO | SteamCaptchaHelper:get_sitekey:56 - 获取gid成功: 9681656522876689 +2025-05-22 20:32:35.414 | INFO | SteamCaptchaHelper:get_sitekey:57 - 获取sitekey成功: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 20:32:35.434 | DEBUG | PynoCaptchaSolver:__init__:21 - PynoCaptchaSolver 初始化 - 使用 PyNoCaptcha 库 +2025-05-22 20:32:35.435 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:31 - 开始解决验证码 - sitekey: eb9cbe72-814a-4392-b9b2-f8965f3686ee +2025-05-22 20:32:35.436 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:32 - 使用User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1741737356) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36 +2025-05-22 20:32:35.437 | DEBUG | pynocaptcha.crackers.base:__init__:58 - 感谢选择 nocaptcha, 我们只做别人做不到的(手动狗头)~ +2025-05-22 20:32:35.439 | DEBUG | pynocaptcha.crackers.base:__init__:59 - 欢迎推荐注册, 官网地址: https://www.nocaptcha.io/ +2025-05-22 20:32:35.440 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:45 - 调用 PyNoCaptcha 进行破解 +2025-05-22 20:32:46.830 | INFO | pynocaptcha.crackers.base:crack:153 - {'status': 1, 'msg': '验证成功', 'id': 'a7132448-c13d-47c2-a43d-45f25fa55fe3', 'cost': '10724.15ms', 'data': {'generated_pass_UUID': 'P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.hadwYXNza2V5xQPLkrRxA4I1L_dNjMveRwgNdFIJwws0gH5K_LcfPtEL_A6eSMvcaXZWDAVmkYKjhuP_-OYLyAPW_JkOIXbINjnsHyhRP7XBQn65fzBQPnZnNZuh-shaKwLiUWGvuU4gUukbOUnzcVUM5p2GDaouW1Y_37-ZuNS_XJ5IfF6CHXT8aQUpMhDkeaKGgsYO3YMfUQDqnDHzyVEJoHLkENLF1F4nDwlPjufw4a-Wh1XHdObypfSRcYk4HXlSLqohxEcFV0y6dJopdbeTi-v6RTBqbykfOOAjht8qa85nZQNwfhPGF_8m6zc5yrLMTvU-_7av6tBbaxfGAvP-kOvjGbRnLJ2FEOePlvLcJ8K3YOadDaIFvqcljXZi98lnX1Qafz4pzZOdXoSBiI5dmsOQF9VJwlDKQ3uv8kRh2BD_53J2czirycIdFV021rkAIWJAxPX6ROVKDpgM2kh-kuMmpvutSfmaSn-P7rbWNVD57Rd4z3Q8HJ3KDPhTbt6NC4sSULHvpi49zcnbNsqOs-5RykiyLgnbgk8n8rfF8Z7aytxj4V5hCUEi8ci8GiUNXxc1SKyNbw4hT1bEa5wVxv0Ju67JYV-Eu5HrnRyZMUNpEkB-S90xYBOstwNEV7ik8jI_G_QXbLTEv7R8Rs_aMBVmmys0zfz0Ei5uCuPf66EQkVkUqEorK7-e26SYF6Zsf9VS4hCySpdxrbLg7nOs1NIqz2D2O9MC_kJmK2PgYSQyA1YW3hnE6TTPEyJxP1BTYPRs5R882TrfryETz_U1XEEAslAhvqjK10SFIIpJBiJNbytsKQpHpaQ3nER0XSKw-jVJ1x27g_IOpSmmXzZQHWz7NZcNflBAe4Pa7oxxxdxoc5RcR8sKTMtyxMOP4aS1ztOlTojx8BzDrnCnKQYRJYyzA4jH54Q0Bm_179j6EN8m26MjxwSpYO3hAtpnnmU5Qj1dmQ6gKAOEB8izxS4ZwH1UcRYIAjHjw4Oqo7S__-DZe5mL7tkg5UVB6weZxxTSBjRrI9rEuzJNN2woULcL1mRGrk23EKtSpxnGqKVgwuORHSBhTs1boOnyQbMtV9Z_EWZ_Dom0QhT73SvuP3WfA_fJhn7VPOsVFOeed6iQcF5apaZJmn1W3c-9KRVxx4FmIlliObdN1wCjD2gXIBM2_AasYdx3XxOtX1hS41zCIR1zWs61kN7eIEXHWRjLwEmIgsYi_6Qtob5-SD--47aY3dsPWp8iUv90eT6MCV0hi2FgNXeotSXPmDo3uJHQU4wZ6S6eFaNSUZegFj-7rKk6y1bzFqOjZXhwzmgvGeaoc2hhcmRfaWTOD3Lqb6JrcqgzNDVlOWNmN6JwZAA.KQolAEKV9I6DIOmDhavMZkJjOSw0tv5xji-3HY20vYQ', 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; Valve Steam Client/default/1745876290) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.183 Safari/537.36'}, 'extra': {}, 'en_msg': 'Verify success'} +2025-05-22 20:32:46.833 | DEBUG | PynoCaptchaSolver:solve_hcaptcha:49 - 验证码破解成功 diff --git a/test_imap.py b/test_imap.py new file mode 100644 index 0000000..83b6332 --- /dev/null +++ b/test_imap.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +测试IMAP邮件获取功能 +单独测试邮箱取件功能 +""" + +import imaplib +import email +import email.header +import sys +from email.parser import BytesParser +from email.policy import default +import re +import time +from urllib.parse import urlparse, parse_qs + +# 邮箱配置 +EMAIL_ADDRESS = "5ulxb79e@evnmail.com" +EMAIL_PASSWORD = "dr!mueh15ahG" +IMAP_SERVER = "mail.evnmail.com" +USE_SSL = True + +def decode_mime_words(text): + """解码MIME编码的文本""" + if not text: + return "" + try: + decoded = email.header.decode_header(text) + return " ".join([ + (str(t[0], t[1] or 'utf-8') if isinstance(t[0], bytes) else str(t[0])) + for t in decoded + ]) + except: + return text + +def get_body_text(msg): + """获取邮件正文文本内容""" + if msg.is_multipart(): + # 如果邮件包含多个部分,递归处理 + text_parts = [] + for part in msg.get_payload(): + if part.get_content_type() == 'text/plain': + charset = part.get_content_charset() or 'utf-8' + try: + text_parts.append(part.get_payload(decode=True).decode(charset)) + except: + text_parts.append("[无法解码的内容]") + elif part.is_multipart(): + # 递归处理多部分 + text_parts.append(get_body_text(part)) + return "\n".join(text_parts) + else: + # 单部分邮件 + content_type = msg.get_content_type() + if content_type == 'text/plain': + charset = msg.get_content_charset() or 'utf-8' + try: + return msg.get_payload(decode=True).decode(charset) + except: + return "[无法解码的内容]" + else: + return f"[内容类型: {content_type}]" + +def extract_urls_from_body(body, pattern): + """从邮件正文中提取URL""" + found_urls = re.findall(pattern, body) + return [url.replace('&', '&').replace("=3D", "=").replace("=\r\n", "") + .replace("\r\n", "").replace("=\n", "").replace("\n", "") + for url in found_urls] + +def test_imap_connection(): + """测试IMAP连接""" + print(f"正在测试连接到 {IMAP_SERVER}...") + try: + # 连接到IMAP服务器 + if USE_SSL: + mail = imaplib.IMAP4_SSL(IMAP_SERVER) + else: + mail = imaplib.IMAP4(IMAP_SERVER) + + # 登录 + print(f"正在登录邮箱 {EMAIL_ADDRESS}...") + mail.login(EMAIL_ADDRESS, EMAIL_PASSWORD) + print("登录成功!") + + # 关闭连接 + mail.logout() + return True + except Exception as e: + print(f"连接失败: {str(e)}") + return False + +def fetch_emails(): + """获取邮件""" + urls = [] + try: + # 连接到IMAP服务器 + if USE_SSL: + mail = imaplib.IMAP4_SSL(IMAP_SERVER) + else: + mail = imaplib.IMAP4(IMAP_SERVER) + + # 登录 + print(f"正在登录邮箱 {EMAIL_ADDRESS}...") + mail.login(EMAIL_ADDRESS, EMAIL_PASSWORD) + print("登录成功!") + + # 只检查INBOX文件夹 + steam_verification_pattern = r'https://store\.steampowered\.com/account/newaccountverification\?[^\s"\'<>]+' + + try: + print("\n检查文件夹: INBOX") + mail.select("INBOX") + status, messages = mail.search(None, "ALL") + if status != "OK" or not messages[0]: + print(" INBOX为空或无法访问") + else: + # 获取邮件ID列表,从最新的开始 + message_ids = messages[0].split() + message_count = len(message_ids) + print(f" 找到 {message_count} 封邮件") + + # 最多检查10封最新邮件 + check_count = min(10, message_count) + message_ids = message_ids[-check_count:] + message_ids.reverse() # 最新的邮件放在前面 + + for i, msg_id in enumerate(message_ids): + print(f"\n 正在检查邮件 {i+1}/{check_count}, ID: {msg_id.decode()}...") + status, msg_data = mail.fetch(msg_id, "(RFC822)") + if status != "OK": + print(" 无法获取邮件内容") + continue + + # 解析邮件内容 + raw_email = msg_data[0][1] + msg = email.message_from_bytes(raw_email, policy=default) + + # 提取信息 + subject = decode_mime_words(msg["Subject"]) + from_addr = decode_mime_words(msg["From"]) + date = decode_mime_words(msg["Date"]) + + print(f" 主题: {subject}") + print(f" 发件人: {from_addr}") + print(f" 日期: {date}") + + # 获取正文 + body = get_body_text(msg) + body_preview = body[:100] + "..." if len(body) > 100 else body + print(f" 正文预览: {body_preview}") + + # 查找Steam验证链接 + found_urls = extract_urls_from_body(body, steam_verification_pattern) + if found_urls: + print(f" 发现 {len(found_urls)} 个可能的Steam验证链接:") + for url in found_urls: + print(f" {url[:80]}...") + urls.append(url) + else: + print(" 未发现Steam验证链接") + except Exception as e: + print(f"处理INBOX出错: {str(e)}") + + # 尝试关闭连接 + try: + mail.close() + except: + pass + mail.logout() + + except Exception as e: + print(f"IMAP连接错误: {str(e)}") + + return urls + +def main(): + print("=" * 60) + print("IMAP邮件获取测试") + print("=" * 60) + + # 测试连接 + if not test_imap_connection(): + print("IMAP连接测试失败,程序退出") + return 1 + + print("\n开始获取邮件...") + urls = fetch_emails() + + if urls: + print("\n" + "=" * 60) + print(f"共找到 {len(urls)} 个可能的Steam验证链接:") + for i, url in enumerate(urls): + print(f"{i+1}. {url}") + else: + print("\n没有找到任何Steam验证链接") + + return 0 + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/启动Steam注册.bat b/启动Steam注册.bat new file mode 100644 index 0000000..8a79f86 --- /dev/null +++ b/启动Steam注册.bat @@ -0,0 +1,5 @@ +@echo off +echo 正在启动Steam注册 V3版本... +echo 这个版本修复了验证码头信息问题,确保使用正确的User-Agent +python start_pyno_v3.py +pause \ No newline at end of file