wangzhibo
2025-07-30 25087cbe79c8c4992551477d55d9db8bbea2202e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
from abc import ABC, abstractmethod
from pathlib import Path
import os
import asyncio
from playwright.async_api import async_playwright, TimeoutError as PlaywrightTimeoutError 
 
from auto_media_publisher.config.conf_base import COOKIE_DIR,PLAYWRIGHT_STEALTH_JS_PATH,DEFAULT_USER_AGENT
from auto_media_publisher.config.conf_platform_login_url import  PLATFORM_LOGIN_MAP
from auto_media_publisher.utils.logger import get_logger
 
 
class LoginChrome(ABC):
    def __init__(self, user,platform,proxy):
        self.user = user
        self.platform = platform
        self.proxy = proxy
        self.cookie_path = os.path.join(COOKIE_DIR, user, f"{platform}.json")
        os.makedirs(os.path.dirname(self.cookie_path), exist_ok=True)
        self.logger = get_logger(platform,user)
        for k, v in PLATFORM_LOGIN_MAP.get(self.platform).items():
            setattr(self, k, v)
    
    @classmethod
    def create_sub_class(cls, user,platform,proxy):   # cls 相当于 self
        return cls(user, platform, proxy)
 
 
    async def _init_browser_context(self,playwright,headless=True):
            """
            初始化 self.browser  and self.context
            如果有 self.proxy,设置
            如果有 self.cookie_path ,设置
            """
            browser_args = {"headless": headless,"channel": "chrome"}
 
            if getattr(self, 'browser_addon_options', None):
                browser_args.update(self.browser_addon_options)
            print(f"start to init browser Using proxy: {self.proxy}")
            if isinstance(self.proxy, str) and self.proxy.strip().lower().startswith(('http://', 'https://')):
                browser_args["proxy"] = {"server": self.proxy}
            self.browser = await playwright.chromium.launch(**browser_args)
            if os.path.exists(self.cookie_path):
                self.context = await self.browser.new_context(storage_state=f"{self.cookie_path}", user_agent=DEFAULT_USER_AGENT,viewport={"width": 1920, "height": 1080})
            else:
                self.context = await self.browser.new_context(user_agent=DEFAULT_USER_AGENT,viewport={"width": 1920, "height": 1080})
            if os.path.exists(PLAYWRIGHT_STEALTH_JS_PATH):
                await self.context.add_init_script(path=Path(PLAYWRIGHT_STEALTH_JS_PATH))
            await self.context.grant_permissions(['geolocation'])
  
    async def check_cookie_valid(self,if_hold_page:bool = False,headless:bool = True,login_url_time_out_ = 100000,login_element_time_out = 300000) -> bool:
        """
        检查当前 cookie 是否有效(如是否已登录)
        默认 if_hold_page = False,就是登录后即退出,不等待
        默认 headless  = False ,就是 不显示浏览器窗口
        """
        async with async_playwright() as playwright:
            await self._init_browser_context(playwright,headless)
                # 创建一个新的页面
            page = await self.context.new_page()
            # 访问指定的 URL
            try:
                self.logger.info(f"{self.user},正在打开{self.login_url}")
                if if_hold_page:
                    login_url_time_out_ = 300000
                await page.goto(self.login_url, timeout=login_url_time_out_)
            except Exception as e:
                self.logger.error(f"[login_chrome] 发生错误:{e}")
            try:
                locator = page.locator(self.login_element)
                await locator.first.wait_for(timeout=login_element_time_out)  # 等待至少一个元素出现
                await self.context.storage_state(path=self.cookie_path)
                self.logger.info(f"check_cookie_valid:{self.user}登录{self.platform}成功,cookie 已保存到 {self.cookie_path}")
                if if_hold_page:
                    while True:
                        await asyncio.sleep(1)
                    
                return True
            except PlaywrightTimeoutError:
                self.logger.error("check_cookie_valid:{self.user}登录{self.platform}失败,等待跳转到目标页面超时,cookie 未保存")
                return False
            
            finally:
                await self.browser.close()
            
    
    async def run(self):
        try:
            self.logger.info(f'[+] 开始检测{self.user}在{self.platform}的登录信息cookie文件是否存在或过期!')
            if not os.path.exists(self.cookie_path) or not await self.check_cookie_valid():
                self.logger.info('[+] cookie文件不存在或已失效,即将自动打开浏览器,请扫码登录,登陆后会自动生成cookie文件')
                await self.check_cookie_valid(if_hold_page=False,headless=False)
            
            return True
        except Exception as e:
            self.logger.error(f"{self.user} login fails :{e}")
            return False
    
    
    async def open(self):
        try:
            await self.check_cookie_valid(if_hold_page=True,headless=False)
            return True
        except Exception as e:
            self.logger.error(f"{self.user} login fails :{e}")
            return False