更新IMAP邮件获取功能和账户保存格式

This commit is contained in:
hkyc
2025-05-22 22:30:08 +08:00
parent 758d8d2f00
commit 4ee6a2e195
21 changed files with 2319 additions and 0 deletions

59
ProxyPool.py Normal file
View File

@@ -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)

83
PynoCaptchaSolver.py Normal file
View File

@@ -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("验证失败")

View File

@@ -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()

113
SteamCaptchaHelper.py Normal file
View File

@@ -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失败")

View File

@@ -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('&amp;', '&').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

155
ThreadManagerWithPyno.py Normal file
View File

@@ -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}")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
accounts_succ.txt Normal file
View File

@@ -0,0 +1 @@
ejd71m5tr----z1xG24ZXbHp----5ulxb79e@evnmail.com----dr!mueh15ahG

12
config.json Normal file
View File

@@ -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
}

1
email_password.txt Normal file
View File

@@ -0,0 +1 @@
5ulxb79e@evnmail.com----dr!mueh15ahG

1
proxy_ips.txt Normal file
View File

@@ -0,0 +1 @@
gw.dataimpulse.com:823:3b9936d2ce39b35c4bdf:2263006e0ff05530

1
rgerror.txt Normal file
View File

@@ -0,0 +1 @@
5ulxb79e@evnmail.com----dr!mueh15ahG

17
start_pyno_v3.py Normal file
View File

@@ -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()

179
steam_registration_pyno.log Normal file
View File

@@ -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 - 验证码破解成功

203
test_imap.py Normal file
View File

@@ -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('&amp;', '&').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())

5
启动Steam注册.bat Normal file
View File

@@ -0,0 +1,5 @@
@echo off
echo 正在启动Steam注册 V3版本...
echo 这个版本修复了验证码头信息问题确保使用正确的User-Agent
python start_pyno_v3.py
pause