127 lines
4.3 KiB
Python
127 lines
4.3 KiB
Python
import requests
|
||
import time
|
||
import json
|
||
from typing import Optional, Dict, Any
|
||
|
||
class TwoCaptchaSolver:
|
||
"""2captcha 腾讯滑块验证码处理器"""
|
||
|
||
def __init__(self, api_key: str):
|
||
self.api_key = api_key
|
||
self.base_url = "http://2captcha.com"
|
||
|
||
def solve_tencent_captcha(self, app_id: str, page_url: str, extra_params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
解决腾讯滑块验证码
|
||
|
||
Args:
|
||
app_id: 腾讯验证码的 app_id
|
||
page_url: 验证码所在页面的 URL
|
||
extra_params: 额外的参数(如果需要)
|
||
|
||
Returns:
|
||
包含验证结果的字典,或 None(如果失败)
|
||
"""
|
||
# 提交验证码任务
|
||
submit_url = f"{self.base_url}/in.php"
|
||
submit_params = {
|
||
"key": self.api_key,
|
||
"method": "tencent",
|
||
"app_id": app_id,
|
||
"pageurl": page_url,
|
||
"json": 1
|
||
}
|
||
|
||
if extra_params:
|
||
submit_params.update(extra_params)
|
||
|
||
try:
|
||
print(f"[2captcha] 提交腾讯验证码任务...")
|
||
response = requests.post(submit_url, data=submit_params)
|
||
result = response.json()
|
||
|
||
if result.get("status") != 1:
|
||
print(f"[2captcha] 提交失败: {result.get('error_text', 'Unknown error')}")
|
||
return None
|
||
|
||
task_id = result.get("request")
|
||
print(f"[2captcha] 任务ID: {task_id}")
|
||
|
||
# 等待并获取结果
|
||
return self._get_result(task_id)
|
||
|
||
except Exception as e:
|
||
print(f"[2captcha] 错误: {str(e)}")
|
||
return None
|
||
|
||
def _get_result(self, task_id: str, max_attempts: int = 60, wait_time: int = 5) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
获取验证码识别结果
|
||
|
||
Args:
|
||
task_id: 2captcha 任务ID
|
||
max_attempts: 最大尝试次数
|
||
wait_time: 每次尝试之间的等待时间(秒)
|
||
|
||
Returns:
|
||
验证结果字典
|
||
"""
|
||
result_url = f"{self.base_url}/res.php"
|
||
|
||
for attempt in range(max_attempts):
|
||
params = {
|
||
"key": self.api_key,
|
||
"action": "get",
|
||
"id": task_id,
|
||
"json": 1
|
||
}
|
||
|
||
try:
|
||
response = requests.get(result_url, params=params)
|
||
result = response.json()
|
||
|
||
if result.get("status") == 1:
|
||
print("[2captcha] 验证码识别成功")
|
||
# 返回腾讯验证码需要的参数
|
||
return {
|
||
"ticket": result.get("request", {}).get("ticket"),
|
||
"randstr": result.get("request", {}).get("randstr"),
|
||
"raw_response": result
|
||
}
|
||
elif result.get("request") == "CAPCHA_NOT_READY":
|
||
print(f"[2captcha] 等待识别中... ({attempt + 1}/{max_attempts})")
|
||
time.sleep(wait_time)
|
||
else:
|
||
print(f"[2captcha] 获取结果失败: {result.get('error_text', 'Unknown error')}")
|
||
return None
|
||
|
||
except Exception as e:
|
||
print(f"[2captcha] 获取结果时出错: {str(e)}")
|
||
time.sleep(wait_time)
|
||
|
||
print("[2captcha] 超时,未能获取验证码结果")
|
||
return None
|
||
|
||
def report_good(self, task_id: str):
|
||
"""报告验证码正确"""
|
||
try:
|
||
requests.get(f"{self.base_url}/res.php", params={
|
||
"key": self.api_key,
|
||
"action": "reportgood",
|
||
"id": task_id
|
||
})
|
||
print("[2captcha] 已报告验证码正确")
|
||
except:
|
||
pass
|
||
|
||
def report_bad(self, task_id: str):
|
||
"""报告验证码错误"""
|
||
try:
|
||
requests.get(f"{self.base_url}/res.php", params={
|
||
"key": self.api_key,
|
||
"action": "reportbad",
|
||
"id": task_id
|
||
})
|
||
print("[2captcha] 已报告验证码错误")
|
||
except:
|
||
pass |