示例demo,页面发现： 确认您是真人， 我通过driver来点击一个 <input type="checkbox">，页面如下：
``` html
<div id="content" style="display: flex;" aria-live="polite" aria-atomic="true">
        <div id="challenge-stage" style="display: flex;"><div class="cb-c" role="alert" style="display: flex;"><label class="cb-lb"><input type="checkbox"><span class="cb-i"></span><span class="cb-lb-t">确认您是真人</span></label></div></div>
        <div id="verifying" class="cb-container" style="display: none; visibility: hidden;">
            <svg id="spinner-icon" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg&#34;   aria-hidden="true" class="unspun">
                <line x1="15" x2="15" y1="1.5" y2="5.5" class="circle"></line>
                <line x1="24.5459" x2="24.5459" y1="5.45405" y2="10.45405" transform="rotate(45 24.5459 5.45405)" class="circle"></line>
                <line x1="28.5" x2="28.5" y1="15" y2="20" transform="rotate(90 28.5 15)" class="circle"></line>
                <line x1="24.5459" x2="24.5459" y1="24.546" y2="29.546" transform="rotate(135 24.5459 24.546)" class="circle"></line>
                <line x1="15" x2="15" y1="28.5" y2="33.5" transform="rotate(180 15 28.5)" class="circle"></line>
                <line x1="5.4541" x2="5.4541" y1="24.5459" y2="29.5459" transform="rotate(-135 5.4541 24.5459)" class="circle"></line>
                <line x1="1.5" x2="1.5" y1="15" y2="20" transform="rotate(-90 1.5 15)" class="circle"></line>
                <line x1="5.45408" x2="5.45408" y1="5.45404" y2="10.45404" transform="rotate(-45 5.45408 5.45404)" class="circle"></line>
            </svg>
            <div id="verifying-msg">
                <span id="verifying-text">正在验证…</span>
                
            </div>
        </div>
        <div id="success" class="cb-container" style="display:none" role="alert">
            <svg id="success-icon" xmlns="http://www.w3.org/2000/svg&#34;   viewBox="0 0 52 52" aria-hidden="true">
                <circle class="success-circle" cx="26" cy="26" r="25"></circle>
                <path class="p1" d="m13,26l9.37,9l17.63,-18"></path>
            </svg>
            <span id="success-text">成功！</span>
        </div>
        <div id="fail" class="cb-container" style="display:none" role="alert">
            <svg id="fail-icon" xmlns="http://www.w3.org/2000/svg&#34;   viewBox="0 0 52 52" aria-hidden="true">
                <circle class="failure-circle" cx="26" cy="26" r="25" fill="none"></circle>
                <path class="failure-cross" fill="none" d="M14.1 27.2 l24.124.2"></path>
            </svg>
            <div id="failure-msg">
                <span id="fail-text">失败！</span>
                <br><span id="fr-helper"><a href="#refresh" id="fr-helper-link">遇到问题？</a></span>
            </div>
        </div>
        <div id="expired" class="cb-container" style="display:none" role="alert">
            <svg id="expired-icon" xmlns="http://www.w3.org/2000/svg&#34;   viewBox="0 0 52 52" aria-hidden="true">
                <circle class="expired-circle" cx="26" cy="26" r="25"></circle>
                <path class="expired-p1" d="m13,32l15,0l0,-23"></path>
            </svg>
            <div id="expiry-msg">
                <span id="expired-text">已过期。</span><a href="#refresh" id="expired-refresh-link">刷新</a>
            </div>
        </div>
        <div id="timeout" class="cb-container" style="display:none" role="alert">
            <svg id="timeout-icon" xmlns="http://www.w3.org/2000/svg&#34;   viewBox="0 0 52 52" aria-hidden="true">
                <circle class="timeout-circle" cx="26" cy="26" r="25"></circle>
                <path class="timeout-p1" d="m13,32l15,0l0,-23"></path>
            </svg>
            <div id="timeout-msg">
                <span id="timeout-text">超时。</span><a href="#refresh" id="timeout-refresh-link">刷新</a>
            </div>
        </div>
        <div id="challenge-error" class="cb-container" style="display:none" role="alert">
            <span id="challenge-error-text"></span>
        </div>
        <div id="branding">
            <a class="cf-link" target="_blank" href="https://www.cloudflare.com/products/turnstile/?utm_source=turnstile&amp;utm_campaign=widget&#34;   rel="noopener noreferrer">
                <svg role="img" aria-label="Cloudflare" id="logo" viewBox="0 0 74 25" fill="none" xmlns="http://www.w3.org/2000/svg&#34;&gt;  
                    <path d="M61.8848 15.7841L62.0632 15.1578C62.2758 14.4126 62.1967 13.7239 61.8401 13.2178C61.5118 12.7517 60.9649 12.4773 60.3007 12.4453L47.7201 12.2836C47.6811 12.2829 47.6428 12.2728 47.6083 12.2542C47.5738 12.2356 47.5442 12.209 47.5217 12.1766C47.4996 12.1431 47.4856 12.1049 47.4807 12.0649C47.4758 12.025 47.4801 11.9844 47.4933 11.9465C47.5149 11.8839 47.5541 11.8291 47.6061 11.7888C47.658 11.7486 47.7204 11.7247 47.7856 11.72L60.4827 11.5566C61.9889 11.4864 63.6196 10.2462 64.1905 8.73372L64.9146 6.81361C64.9443 6.73242 64.951 6.64444 64.9341 6.55957C64.112 2.80652 60.8115 0 56.8652 0C53.2293 0 50.1421 2.38158 49.0347 5.69186C48.2864 5.12186 47.3535 4.85982 46.4228 4.95823C44.6785 5.13401 43.276 6.55928 43.1034 8.32979C43.059 8.77189 43.0915 9.21845 43.1992 9.64918C40.3497 9.73347 38.0645 12.1027 38.0645 15.0151C38.0649 15.2751 38.0838 15.5347 38.1212 15.7919C38.1294 15.8513 38.1584 15.9057 38.2029 15.9452C38.2474 15.9847 38.3044 16.0067 38.3635 16.0071L61.5894 16.0099C61.5916 16.0101 61.5938 16.0101 61.596 16.0099C61.6616 16.0088 61.7252 15.9862 61.7772 15.9455C61.8293 15.9049 61.867 15.8483 61.8848 15.7841Z" fill="#F6821F"></path>
                    <path d="M66.0758 6.95285C65.9592 6.95285 65.843 6.95582 65.7274 6.96177C65.7087 6.96312 65.6904 6.96719 65.6729 6.97385C65.6426 6.98437 65.6152 7.00219 65.5931 7.02579C65.5711 7.04939 65.555 7.07806 65.5462 7.10936L65.0515 8.84333C64.8389 9.58847 64.918 10.2766 65.2749 10.7827C65.6029 11.2494 66.1498 11.5233 66.814 11.5552L69.4959 11.7186C69.5336 11.7199 69.5705 11.73 69.6037 11.7483C69.6369 11.7666 69.6654 11.7925 69.687 11.8239C69.7092 11.8576 69.7234 11.896 69.7283 11.9363C69.7332 11.9765 69.7288 12.0173 69.7153 12.0555C69.6937 12.118 69.6546 12.1727 69.6028 12.2129C69.5509 12.2531 69.4887 12.2771 69.4236 12.2819L66.6371 12.4453C65.1241 12.5161 63.4937 13.7558 62.9233 15.2682L62.722 15.8022C62.7136 15.8245 62.7105 15.8486 62.713 15.8724C62.7155 15.8961 62.7236 15.9189 62.7365 15.9389C62.7495 15.9589 62.7669 15.9755 62.7874 15.9873C62.8079 15.9991 62.8309 16.0058 62.8544 16.0068C62.8569 16.0068 62.8592 16.0068 62.8618 16.0068H72.4502C72.506 16.0073 72.5604 15.9893 72.6051 15.9554C72.6498 15.9216 72.6823 15.8739 72.6977 15.8195C72.8677 15.2043 72.9535 14.5684 72.9529 13.9296C72.9517 10.0767 69.8732 6.95285 66.0758 6.95285Z" fill="#FBAD41"></path>
                    <path class="logo-text" d="M8.11963 18.8904H9.75541V23.4254H12.6139V24.8798H8.11963V18.8904Z"></path>
                    <path class="logo-text" d="M14.3081 21.9023V21.8853C14.3081 20.1655 15.674 18.7704 17.4952 18.7704C19.3164 18.7704 20.6653 20.1482 20.6653 21.8681V21.8853C20.6653 23.6052 19.2991 24.9994 17.4785 24.9994C15.6578 24.9994 14.3081 23.6222 14.3081 21.9023ZM18.9958 21.9023V21.8853C18.9958 21.0222 18.3806 20.2679 17.4785 20.2679C16.5846 20.2679 15.9858 21.0038 15.9858 21.8681V21.8853C15.9858 22.7484 16.6013 23.5025 17.4952 23.5025C18.3973 23.5025 18.9958 22.7666 18.9958 21.9023Z"></path>
                    <path class="logo-text" d="M22.6674 22.253V18.8901H24.3284V22.2191C24.3284 23.0822 24.7584 23.4939 25.4159 23.4939C26.0733 23.4939 26.5034 23.1003 26.5034 22.2617V18.8901H28.1647V22.2093C28.1647 24.1432 27.0772 24.9899 25.3991 24.9899C23.7211 24.9899 22.6674 24.1268 22.6674 22.2522"></path>
                    <path class="logo-text" d="M30.668 18.8907H32.9445C35.0526 18.8907 36.275 20.1226 36.275 21.8508V21.8684C36.275 23.5963 35.0355 24.88 32.911 24.88H30.668V18.8907ZM32.97 23.4076C33.9483 23.4076 34.597 22.8609 34.597 21.8928V21.8759C34.597 20.9178 33.9483 20.3614 32.97 20.3614H32.3038V23.4082L32.97 23.4076Z"></path>
                    <path class="logo-text" d="M38.6525 18.8904H43.3738V20.3453H40.2883V21.3632H43.079V22.7407H40.2883V24.8798H38.6525V18.8904Z"></path>
                    <path class="logo-text" d="M45.65 18.8904H47.2858V23.4254H50.1443V24.8798H45.65V18.8904Z"></path>
                    <path class="logo-text" d="M54.4187 18.8475H55.9949L58.5079 24.8797H56.7541L56.3238 23.8101H54.047L53.6257 24.8797H51.9058L54.4187 18.8475ZM55.8518 22.5183L55.1941 20.8154L54.5278 22.5183H55.8518Z"></path>
                    <path class="logo-text" d="M60.6149 18.8901H63.4056C64.3083 18.8901 64.9317 19.13 65.328 19.5406C65.6742 19.883 65.8511 20.3462 65.8511 20.9357V20.9526C65.8511 21.8678 65.3691 22.4754 64.6369 22.7919L66.045 24.88H64.1558L62.9671 23.0658H62.2507V24.88H60.6149V18.8901ZM63.3299 21.7654C63.8864 21.7654 64.2071 21.4915 64.2071 21.0551V21.0381C64.2071 20.5674 63.8697 20.328 63.3211 20.328H62.2507V21.7665L63.3299 21.7654Z"></path>
                    <path class="logo-text" d="M68.2112 18.8904H72.9578V20.3024H69.8302V21.209H72.6632V22.5183H69.8302V23.4683H73V24.8798H68.2112V18.8904Z"></path>
                    <path class="logo-text" d="M4.53824 22.6043C4.30918 23.13 3.82723 23.5022 3.18681 23.5022C2.29265 23.5022 1.67746 22.7493 1.67746 21.8851V21.8678C1.67746 21.0047 2.27593 20.2676 3.1698 20.2676C3.84367 20.2676 4.35681 20.6882 4.5734 21.2605H6.29764C6.02151 19.8349 4.78716 18.7707 3.18681 18.7707C1.36533 18.7707 0 20.1666 0 21.8851V21.9021C0 23.6219 1.3486 25 3.1698 25C4.72762 25 5.94525 23.9764 6.26645 22.6046L4.53824 22.6043Z"></path>
                </svg>
            </a>
            <div id="terms">
                <a id="privacy-link" target="_blank" rel="noopener noreferrer" href="<url id="" type="url" status="" title="" wc="">https://www.cloudflare.com/zh-cn/privacypolicy/">隐私</a><span</url>  class="link-spacer"> • </span><a id="terms-link" target="_blank" rel="noopener noreferrer" href="<url id="" type="url" status="" title="" wc="">https://www.cloudflare.com/zh-cn/website-terms/">条款</a></url> 
            </div>
        </div>
    </div>



```

安装如下代码，帮我封装。 注意只使用DrissionPage：


``` python
import time
from DrissionPage import ChromiumPage


class CloudflareBypasserA:
    def __init__(self, driver: ChromiumPage):
        self.driver = driver
    # 外部调用方法
    def bypass(self):
        while True:
            try:
                if self.driver.ele_displayed('//input[@type="checkbox"]', timeout=10):
                    self.driver.click('//input[@type="checkbox"]')
                    time.sleep(2)  # 点击后等待一段时间，观察是否有反应
            except Exception as e:
                print(f"Error clicking the checkbox: {e}")
                break  
            time.sleep(5)
```


类ChromiumPage 远吗如下：

```
# -*- coding:utf-8 -*-
"""
@Author   : g1879
@Contact  : <PRESIDIO_ANONYMIZED_EMAIL_ADDRESS>
@Copyright: (c) 2024 by g1879, Inc. All Rights Reserved.
@License  : BSD 3-Clause.
"""
from pathlib import Path
from threading import Lock
from time import sleep, perf_counter

from requests import Session

from .._base.browser import Browser
from .._configs.chromium_options import ChromiumOptions
from .._functions.browser import connect_browser
from .._functions.settings import Settings
from .._functions.tools import PortFinder
from .._functions.web import save_page
from .._pages.chromium_base import ChromiumBase, Timeout
from .._pages.chromium_tab import ChromiumTab
from .._units.setter import ChromiumPageSetter
from .._units.waiter import PageWaiter
from ..errors import BrowserConnectError


class ChromiumPage(ChromiumBase):
    """用于管理浏览器的类"""
    _PAGES = {}

    def __new__(cls, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None):
        """
        :param addr_or_opts: 浏览器地址:端口、ChromiumOptions对象或端口数字（int）
        :param tab_id: 要控制的标签页id，不指定默认为激活的
        :param timeout: 超时时间（秒）
        """
        addr_or_opts = addr_or_opts or addr_driver_opts
        opt = handle_options(addr_or_opts)
        is_exist, browser_id = run_browser(opt)
        if browser_id in cls._PAGES:
            r = cls._PAGES[browser_id]
            while not hasattr(r, '_frame_id'):
                sleep(.1)
            return r
        r = object.__new__(cls)
        r._chromium_options = opt
        r._is_exist = is_exist
        r._browser_id = browser_id
        r.address = opt.address
        cls._PAGES[browser_id] = r
        return r

    def __init__(self, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None):
        """
        :param addr_or_opts: 浏览器地址:端口、ChromiumOptions对象或端口数字（int）
        :param tab_id: 要控制的标签页id，不指定默认为激活的
        :param timeout: 超时时间（秒）
        """
        if hasattr(self, '_created'):
            return
        self._created = True

        self._page = self
        self.tab = self
        self._run_browser()
        super().__init__(self.address, tab_id)
        self._type = 'ChromiumPage'
        self._lock = Lock()
        self.set.timeouts(base=timeout)
        self._page_init()

    def _run_browser(self):
        """连接浏览器"""
        self._browser = Browser(self._chromium_options.address, self._browser_id, self)
        r = self._browser.run_cdp('Browser.getVersion')
        self._browser_version = r['product']
        if self._is_exist and self._chromium_options._headless is False and 'headless' in r['userAgent'].lower():
            self._browser.quit(3)
            connect_browser(self._chromium_options)
            s = Session()
            s.trust_env = False
            ws = s.get(f'http://{self._chromium_options.address}/json/version', headers={'Connection': 'close'})
            bid = ws.json()['webSocketDebuggerUrl'].split('/')[-1]
            self._browser = Browser(self._chromium_options.address, bid, self)
            ws.close()
            s.close()

    def _d_set_runtime_settings(self):
        """设置运行时用到的属性"""
        self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['page_load'],
                                 script=self._chromium_options.timeouts['script'],
                                 base=self._chromium_options.timeouts['base'])
        if self._chromium_options.timeouts['base'] is not None:
            self._timeout = self._chromium_options.timeouts['base']
        self._load_mode = self._chromium_options.load_mode
        self._download_path = None if self._chromium_options.download_path is None \
            else str(Path(self._chromium_options.download_path).absolute())
        self.retry_times = self._chromium_options.retry_times
        self.retry_interval = self._chromium_options.retry_interval

    def _page_init(self):
        """浏览器相关设置"""
        self._browser.connect_to_page()

    # ----------挂件----------

    @property
    def set(self):
        """返回用于设置的对象"""
        if self._set is None:
            self._set = ChromiumPageSetter(self)
        return self._set

    @property
    def wait(self):
        """返回用于等待的对象"""
        if self._wait is None:
            self._wait = PageWaiter(self)
        return self._wait

    # ----------挂件----------

    @property
    def browser(self):
        """返回用于控制浏览器cdp的driver"""
        return self._browser

    @property
    def tabs_count(self):
        """返回标签页数量"""
        return self.browser.tabs_count

    @property
    def tab_ids(self):
        """返回所有标签页id组成的列表"""
        return self.browser.tab_ids

    @property
    def latest_tab(self):
        """返回最新的标签页，最新标签页指最后创建或最后被激活的
        当Settings.singleton_tab_obj==True时返回Tab对象，否则返回tab id"""
        return self.get_tab(self.tab_ids[0], as_id=not Settings.singleton_tab_obj)

    @property
    def process_id(self):
        """返回浏览器进程id"""
        return self.browser.process_id

    @property
    def browser_version(self):
        """返回所控制的浏览器版本号"""
        return self._browser_version

    def save(self, path=None, name=None, as_pdf=False, **kwargs):
        """把当前页面保存为文件，如果path和name参数都为None，只返回文本
        :param path: 保存路径，为None且name不为None时保存在当前路径
        :param name: 文件名，为None且path不为None时用title属性值
        :param as_pdf: 为Ture保存为pdf，否则为mhtml且忽略kwargs参数
        :param kwargs: pdf生成参数
        :return: as_pdf为True时返回bytes，否则返回文件文本
        """
        return save_page(self, path, name, as_pdf, kwargs)

    def get_tab(self, id_or_num=None, title=None, url=None, tab_type='page', as_id=False):
        """获取一个标签页对象，id_or_num不为None时，后面几个参数无效
        :param id_or_num: 要获取的标签页id或序号，序号从1开始，可传入负数获取倒数第几个，不是视觉排列顺序，而是激活顺序
        :param title: 要匹配title的文本，模糊匹配，为None则匹配所有
        :param url: 要匹配url的文本，模糊匹配，为None则匹配所有
        :param tab_type: tab类型，可用列表输入多个，如 'page', 'iframe' 等，为None则匹配所有
        :param as_id: 是否返回标签页id而不是标签页对象
        :return: ChromiumTab对象
        """
        if id_or_num is not None:
            if isinstance(id_or_num, str):
                id_or_num = id_or_num
            elif isinstance(id_or_num, int):
                id_or_num = self.tab_ids[id_or_num - 1 if id_or_num > 0 else id_or_num]
            elif isinstance(id_or_num, ChromiumTab):
                if as_id:
                    return id_or_num.tab_id
                elif Settings.singleton_tab_obj:
                    return id_or_num
                else:
                    return self.get_tab(id_or_num.tab_id)

        elif title == url == tab_type is None:
            id_or_num = self.tab_id

        else:
            id_or_num = self._browser.find_tabs(title, url, tab_type)
            if id_or_num:
                id_or_num = id_or_num[0]['id']
            else:
                return None

        if as_id:
            return id_or_num

        with self._lock:
            return ChromiumTab(self, id_or_num)

    def get_tabs(self, title=None, url=None, tab_type='page', as_id=False):
        """查找符合条件的tab，返回它们组成的列表
        :param title: 要匹配title的文本，模糊匹配，为None则匹配所有
        :param url: 要匹配url的文本，模糊匹配，为None则匹配所有
        :param tab_type: tab类型，可用列表输入多个，如 'page', 'iframe' 等，为None则匹配所有
        :param as_id: 是否返回标签页id而不是标签页对象
        :return: ChromiumTab对象组成的列表
        """
        if as_id:
            return [tab['id'] for tab in self._browser.find_tabs(title, url, tab_type)]
        with self._lock:
            return [ChromiumTab(self, tab['id']) for tab in self._browser.find_tabs(title, url, tab_type)]

    def new_tab(self, url=None, new_window=False, background=False, new_context=False):
        """新建一个标签页
        :param url: 新标签页跳转到的网址
        :param new_window: 是否在新窗口打开标签页
        :param background: 是否不激活新标签页，如new_window为True则无效
        :param new_context: 是否创建新的上下文
        :return: 新标签页对象
        """
        tab = ChromiumTab(self, tab_id=self.browser.new_tab(new_window, background, new_context))
        if url:
            tab.get(url)
        return tab

    def close(self):
        """关闭Page管理的标签页"""
        self.close_tabs(self.tab_id)

    def close_tabs(self, tabs_or_ids=None, others=False):
        """关闭传入的标签页，默认关闭当前页。可传入多个
        :param tabs_or_ids: 要关闭的标签页对象或id，可传入列表或元组，为None时关闭当前页
        :param others: 是否关闭指定标签页之外的
        :return: None
        """
        all_tabs = set(self.tab_ids)
        if isinstance(tabs_or_ids, str):
            tabs = {tabs_or_ids}
        elif isinstance(tabs_or_ids, ChromiumTab):
            tabs = {tabs_or_ids.tab_id}
        elif tabs_or_ids is None:
            tabs = {self.tab_id}
        elif isinstance(tabs_or_ids, (list, tuple)):
            tabs = set(i.tab_id if isinstance(i, ChromiumTab) else i for i in tabs_or_ids)
        else:
            raise TypeError('tabs_or_ids参数只能传入标签页对象或id。')

        if others:
            tabs = all_tabs - tabs

        end_len = len(set(all_tabs) - set(tabs))
        if end_len <= 0:
            self.quit()
            return

        for tab in tabs:
            self.browser.close_tab(tab)
            sleep(.2)
        end_time = perf_counter() + 3
        while self.tabs_count != end_len and perf_counter() < end_time:
            sleep(.1)

    def quit(self, timeout=5, force=True):
        """关闭浏览器
        :param timeout: 等待浏览器关闭超时时间（秒）
        :param force: 关闭超时是否强制终止进程
        :return: None
        """
        self.browser.quit(timeout, force)

    def _on_disconnect(self):
        """浏览器退出时执行"""
        ChromiumPage._PAGES.pop(self._browser_id, None)

    def __repr__(self):
        return f'<ChromiumPage browser_id={self.browser.id} tab_id={self.tab_id}>'

    # ----------即将废弃-----------
    def close_other_tabs(self, tabs_or_ids=None):
        """关闭传入的标签页以外标签页，默认保留当前页。可传入多个
        :param tabs_or_ids: 要保留的标签页对象或id，可传入列表或元组，为None时保存当前页
        :return: None
        """
        self.close_tabs(tabs_or_ids, True)

    @property
    def tabs(self):
        """返回所有标签页id组成的列表"""
        return self.browser.tab_ids

    def find_tabs(self, title=None, url=None, tab_type=None, single=True):
        """查找符合条件的tab，返回它们组成的列表
        :param title: 要匹配title的文本
        :param url: 要匹配url的文本
        :param tab_type: tab类型，可用列表输入多个
        :param single: 是否返回首个结果的id，为False返回所有信息
        :return: tab id或tab列表
        """
        r = self._browser.find_tabs(title, url, tab_type)
        return r[0]['id'] if r and single else r


def handle_options(addr_or_opts):
    """设置浏览器启动属性
    :param addr_or_opts: 'ip:port'、ChromiumOptions、Driver
    :return: 返回ChromiumOptions对象
    """
    if not addr_or_opts:
        _chromium_options = ChromiumOptions(addr_or_opts)
        if _chromium_options.is_auto_port:
            port, path = PortFinder(_chromium_options.tmp_path).get_port(_chromium_options.is_auto_port)
            _chromium_options.set_address(f'127.0.0.1:{port}')
            _chromium_options.set_user_data_path(path)
            _chromium_options.auto_port(scope=_chromium_options.is_auto_port)

    elif isinstance(addr_or_opts, ChromiumOptions):
        if addr_or_opts.is_auto_port:
            port, path = PortFinder(addr_or_opts.tmp_path).get_port(addr_or_opts.is_auto_port)
            addr_or_opts.set_address(f'127.0.0.1:{port}')
            addr_or_opts.set_user_data_path(path)
            addr_or_opts.auto_port(scope=addr_or_opts.is_auto_port)
        _chromium_options = addr_or_opts

    elif isinstance(addr_or_opts, str):
        _chromium_options = ChromiumOptions()
        _chromium_options.set_address(addr_or_opts)

    elif isinstance(addr_or_opts, int):
        _chromium_options = ChromiumOptions()
        _chromium_options.set_local_port(addr_or_opts)

    else:
        raise TypeError('只能接收ip:port格式或ChromiumOptions类型参数。')

    return _chromium_options


def run_browser(chromium_options):
    """连接浏览器"""
    is_exist = connect_browser(chromium_options)
    try:
        s = Session()
        s.trust_env = False
        ws = s.get(f'http://{chromium_options.address}/json/version', headers={'Connection': 'close'})
        if not ws:
            raise BrowserConnectError('\n浏览器连接失败，如使用全局代理，须设置不代理127.0.0.1地址。')
        browser_id = ws.json()['webSocketDebuggerUrl'].split('/')[-1]
        ws.close()
        s.close()
    except KeyError:
        raise BrowserConnectError('浏览器版本太旧或此浏览器不支持接管。')
    except:
        raise BrowserConnectError('\n浏览器连接失败，如使用全局代理，须设置不代理127.0.0.1地址。')
    return is_exist, browser_id


def get_rename(original, rename):
    if '.' in rename:
        return rename
    else:
        suffix = original[original.rfind('.'):] if '.' in original else ''
        return f'{rename}{suffix}'

```