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 0000000..536b1a2 Binary files /dev/null and b/__pycache__/ProxyPool.cpython-312.pyc differ diff --git a/__pycache__/PynoCaptchaSolver.cpython-312.pyc b/__pycache__/PynoCaptchaSolver.cpython-312.pyc new file mode 100644 index 0000000..5c6dd1c Binary files /dev/null and b/__pycache__/PynoCaptchaSolver.cpython-312.pyc differ diff --git a/__pycache__/RegistrationGUIWithPynoV2.cpython-312.pyc b/__pycache__/RegistrationGUIWithPynoV2.cpython-312.pyc new file mode 100644 index 0000000..9648e6b Binary files /dev/null and b/__pycache__/RegistrationGUIWithPynoV2.cpython-312.pyc differ diff --git a/__pycache__/SteamCaptchaHelper.cpython-312.pyc b/__pycache__/SteamCaptchaHelper.cpython-312.pyc new file mode 100644 index 0000000..71ee822 Binary files /dev/null and b/__pycache__/SteamCaptchaHelper.cpython-312.pyc differ diff --git a/__pycache__/SteamRegistrationWithPyno.cpython-312.pyc b/__pycache__/SteamRegistrationWithPyno.cpython-312.pyc new file mode 100644 index 0000000..c5ddd57 Binary files /dev/null and b/__pycache__/SteamRegistrationWithPyno.cpython-312.pyc differ diff --git a/__pycache__/ThreadManagerWithPyno.cpython-312.pyc b/__pycache__/ThreadManagerWithPyno.cpython-312.pyc new file mode 100644 index 0000000..8ba4951 Binary files /dev/null and b/__pycache__/ThreadManagerWithPyno.cpython-312.pyc differ 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