58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
|
|
import asyncio
|
|||
|
|
import json
|
|||
|
|
import os
|
|||
|
|
from playwright.async_api import async_playwright
|
|||
|
|
from utils.stealth import stealth_async
|
|||
|
|
|
|||
|
|
class Authenticator:
|
|||
|
|
def __init__(self, auth_file="auth_state.json"):
|
|||
|
|
self.auth_file = auth_file
|
|||
|
|
|
|||
|
|
async def login(self, initial_url="https://weidian.com/"):
|
|||
|
|
"""
|
|||
|
|
打开浏览器由用户手动扫码登录。
|
|||
|
|
登录成功后保存 session state。
|
|||
|
|
"""
|
|||
|
|
async with async_playwright() as p:
|
|||
|
|
browser = await p.chromium.launch(headless=False, args=['--disable-gpu'])
|
|||
|
|
# 模拟 iPhone 13 配置以确保显示手机版界面
|
|||
|
|
device = p.devices['iPhone 13']
|
|||
|
|
context = await browser.new_context(**device)
|
|||
|
|
page = await context.new_page()
|
|||
|
|
await stealth_async(page)
|
|||
|
|
|
|||
|
|
await page.goto(initial_url)
|
|||
|
|
print("请在浏览器中完成登录(扫码等操作)...")
|
|||
|
|
|
|||
|
|
# 等待用户手动登录,直到 cookie 中出现登录凭证或 URL 变化
|
|||
|
|
# 这里简单处理,等待用户按回车确认已登录
|
|||
|
|
await asyncio.get_event_loop().run_in_executor(None, input, "登录完成后请在这里按回车控制台继续...")
|
|||
|
|
|
|||
|
|
# 保存状态
|
|||
|
|
storage = await context.storage_state(path=self.auth_file)
|
|||
|
|
print(f"登录状态已保存至 {self.auth_file}")
|
|||
|
|
|
|||
|
|
await browser.close()
|
|||
|
|
|
|||
|
|
def has_auth(self):
|
|||
|
|
return os.path.exists(self.auth_file)
|
|||
|
|
|
|||
|
|
async def get_context(self, playwright_instance, headless=False):
|
|||
|
|
"""
|
|||
|
|
创建一个带有已保存状态的 context,并模拟手机环境
|
|||
|
|
"""
|
|||
|
|
browser = await playwright_instance.chromium.launch(headless=headless, args=['--disable-gpu'])
|
|||
|
|
|
|||
|
|
# 模拟 iPhone 13 配置
|
|||
|
|
device = playwright_instance.devices['iPhone 13']
|
|||
|
|
|
|||
|
|
if self.has_auth():
|
|||
|
|
context = await browser.new_context(
|
|||
|
|
**device,
|
|||
|
|
storage_state=self.auth_file
|
|||
|
|
)
|
|||
|
|
else:
|
|||
|
|
context = await browser.new_context(**device)
|
|||
|
|
|
|||
|
|
return browser, context
|