commit
This commit is contained in:
@@ -497,6 +497,83 @@ class XHSLoginService:
|
||||
except Exception as e:
|
||||
print(f"关闭浏览器异常: {str(e)}", file=sys.stderr)
|
||||
|
||||
async def extract_verification_qrcode(self) -> Optional[str]:
|
||||
"""
|
||||
提取验证页面的二维码图片
|
||||
|
||||
Returns:
|
||||
二维码图片的base64数据,如果提取失败则返回none
|
||||
"""
|
||||
try:
|
||||
if not self.page:
|
||||
return None
|
||||
|
||||
print("正在提取验证二维码...", file=sys.stderr)
|
||||
|
||||
# 尝试查找二维码图片元素
|
||||
qrcode_selectors = [
|
||||
'.qrcode-img', # 根据您提供的HTML
|
||||
'img.qrcode-img',
|
||||
'.qrcode-container img',
|
||||
'img[src*="data:image"]', # base64图片
|
||||
'img[src*="qrcode"]',
|
||||
'img[alt*="二维码"]',
|
||||
'img[alt*="qrcode"]',
|
||||
]
|
||||
|
||||
for selector in qrcode_selectors:
|
||||
try:
|
||||
qrcode_img = await self.page.wait_for_selector(selector, timeout=3000)
|
||||
if qrcode_img:
|
||||
print(f"✅ 找到二维码图片: {selector}", file=sys.stderr)
|
||||
|
||||
# 获取图片src属性
|
||||
src = await qrcode_img.get_attribute('src')
|
||||
if src:
|
||||
# 如果是base64格式,直接返回
|
||||
if src.startswith('data:image'):
|
||||
print("✅ 二维码已是base64格式,直接返回", file=sys.stderr)
|
||||
return src
|
||||
|
||||
# 如果是URL,尝试下载并转换为base64
|
||||
print(f"二维码是URL格式: {src[:100]}...", file=sys.stderr)
|
||||
try:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(src, timeout=aiohttp.ClientTimeout(total=10)) as response:
|
||||
if response.status == 200:
|
||||
img_data = await response.read()
|
||||
import base64
|
||||
img_base64 = base64.b64encode(img_data).decode('utf-8')
|
||||
# 根据内容类型确定格式
|
||||
content_type = response.headers.get('Content-Type', 'image/png')
|
||||
base64_str = f"data:{content_type};base64,{img_base64}"
|
||||
print("✅ 成功下载并转换为base64", file=sys.stderr)
|
||||
return base64_str
|
||||
except Exception as e:
|
||||
print(f"⚠️ 下载二维码图片失败: {str(e)}", file=sys.stderr)
|
||||
|
||||
# 如果src方法失败,尝试截图
|
||||
print("尝试截取二维码区域...", file=sys.stderr)
|
||||
screenshot_bytes = await qrcode_img.screenshot()
|
||||
if screenshot_bytes:
|
||||
import base64
|
||||
img_base64 = base64.b64encode(screenshot_bytes).decode('utf-8')
|
||||
base64_str = f"data:image/png;base64,{img_base64}"
|
||||
print("✅ 成功截取二维码并转换为base64", file=sys.stderr)
|
||||
return base64_str
|
||||
|
||||
break
|
||||
except Exception as e:
|
||||
print(f"尝试选择器 {selector} 失败: {str(e)}", file=sys.stderr)
|
||||
continue
|
||||
|
||||
print("⚠️ 未找到二维码图片", file=sys.stderr)
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
print(f"⚠️ 提取二维码失败: {str(e)}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
async def send_verification_code(self, phone: str, country_code: str = "+86", login_page: str = "creator") -> Dict[str, Any]:
|
||||
"""
|
||||
发送验证码
|
||||
@@ -819,16 +896,32 @@ class XHSLoginService:
|
||||
await send_code_btn.click()
|
||||
print("✅ 已点击发送验证码", file=sys.stderr)
|
||||
|
||||
# # 优化:简化二次协议处理
|
||||
# await asyncio.sleep(0.3) # 等待协议弹窗可能出现
|
||||
# try:
|
||||
# agreement_btn = await self.page.query_selector('text="同意并继续"')
|
||||
# if agreement_btn:
|
||||
# await agreement_btn.click()
|
||||
# print(f"✅ 再次点击协议按钮", file=sys.stderr)
|
||||
# await asyncio.sleep(0.2)
|
||||
# except Exception:
|
||||
# pass # 无二次协议弹窗
|
||||
# 等待页面响应,检测是否出现验证二维码
|
||||
await asyncio.sleep(1.5)
|
||||
|
||||
# 检查当前页面URL是否包含captcha(验证页面)
|
||||
current_url = self.page.url
|
||||
if 'captcha' in current_url or 'verify' in current_url:
|
||||
print(f"⚠️ 检测到验证页面: {current_url}", file=sys.stderr)
|
||||
|
||||
# 尝试提取二维码图片
|
||||
qrcode_data = await self.extract_verification_qrcode()
|
||||
if qrcode_data:
|
||||
print("✅ 成功提取验证二维码", file=sys.stderr)
|
||||
return {
|
||||
"success": False,
|
||||
"need_captcha": True,
|
||||
"captcha_type": "qrcode",
|
||||
"qrcode_image": qrcode_data,
|
||||
"message": "需要扫码验证,请使用小红书APP扫描二维码"
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"success": False,
|
||||
"need_captcha": True,
|
||||
"captcha_type": "unknown",
|
||||
"message": "出现验证码验证,请稍后重试"
|
||||
}
|
||||
|
||||
# 直接返回成功,不再检测滑块
|
||||
print("\n✅ 验证码发送流程完成,请查看手机短信", file=sys.stderr)
|
||||
|
||||
Reference in New Issue
Block a user