• selenium-封装一个browser


    • browser: 浏览器
    • 封装了浏览器相关操作
    • 创建一个默认浏览器:Browser()
    • 浏览器默认配置:Browser.DEFAULT_CONFIG
    • 创建自定义浏览器:Browser(config=config),config根据默认配置的数据结构传入即可
    import importlib
    from selenium.webdriver import Chrome, ChromeOptions, ActionChains
    from selenium.webdriver.remote.webdriver import WebDriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as ec
    
    from loguru import logger
    from collections import namedtuple, defaultdict
    
    Locator = namedtuple('Locator', ('type', 'value'))
    
    
    class Browser:
        MAX_TIMEOUT = 30
        DEFAULT_CONFIG = {
            'browser': 'Chrome',
            # 显示等待超时时间
            'timeout': MAX_TIMEOUT,
            # 地址栏搜索页面加载超时时间
            'page_max_load_time': MAX_TIMEOUT,
            'browser_options':{
                # 浏览器-无界面模式
                '--headless': False,
                # 浏览器-root权限
                '--no-sandbox': True,
                # 浏览器-禁用共享内存
                '--disable-dev-shm-usage': True
            }
    
        }
    
        def __init__(self, config=None):
            # 加载配置
            config = config or {}
            self.config = {**Browser.DEFAULT_CONFIG, **config}
            # 创建驱动
            self.driver = Browser.create_driver(self.config)
            # 全屏
            self.driver.maximize_window()
            # 隐式等待
            self.driver.implicitly_wait(self.config.get('timeout'))
            # 显示等待
            self.waiter = WebDriverWait(self.driver, timeout=self.config.get('timeout'))
            # 元素操作
            self.action = ActionChains(self.driver)
            logger.info(f'初始化浏览器配置 => {self.config}')
    
        @staticmethod
        def create_driver(config) -> WebDriver:
            # 获取配置信息
            browser_name = config.get('browser')
            browser_options_name = browser_name + 'Options'
            browser_options_kwargs = config.get('browser_options')
    
            # 动态导入模块
            webdriver = importlib.import_module('selenium.webdriver.__init__')
    
            # 根据配置创建浏览器驱动和配置
            browser_class = getattr(webdriver, browser_name)
    
            browser_options = getattr(webdriver, browser_options_name)()
            for k, v in browser_options_kwargs.items():
                if v is True:
                    browser_options.add_argument(k)
    
            return browser_class(options=browser_options)
    
    
        # js操作
        def js(self, script: str, *args):
            logger.info(f'js操作 => {script}({args})')
            self.driver.execute_script(script, *args)
    
        # 页面级操作
    
        def search(self, url):
            logger.info(f'当前页面地址栏输入 => {url}')
            self.driver.set_page_load_timeout(self.config.get('page_max_load_time'))
            self.driver.get(url)
    
        def f5(self):
            logger.info('刷新当前页面')
            self.driver.refresh()
    
        def close_window(self):
            logger.info('关闭当前窗口')
            self.driver.close()
    
        def quit_browser(self):
            logger.info('关闭浏览器')
            self.driver.quit()
    
        @property
        def html(self):
            _ = self.driver.page_source
            logger.info(f'源码 => {_}')
            return _
    
        def to_window(self, handle):
            logger.info(f'跳转到指定窗口 => {handle}')
            self.driver.switch_to.window(handle)
    
        def current_window(self):
            _ = self.driver.current_window_handle
            logger.info(f'当前窗口 => {_}')
            return self.driver.current_window_handle
    
        def all_window(self):
            _ = self.driver.window_handles
            logger.info(f'所有窗口 => {_}')
            return _
    
        def to_frame_by_element(self, locator):
            # 这里只支持通过子元素进入,如果需要通过引用则重写
            logger.info(f'进入{locator}元素所在frame => {locator}')
            self.driver.switch_to.frame(self.find_elements(locator))
    
        def move_to_by_element(self, locator):
            logger.info(f'窗口显示位置移到到{locator}')
            self.action.move_to_element(self.find_element(locator))
    
        def move_to_by_js(self, x=100000, y=100000):
            # 未传参 或 超出了范围 则 滑到末尾
            logger.info(f'js滑动窗口 => window.scrollTo({x},{y})')
            x = x if 0<=x<=100000 else 100000
            y = y if 0<=x<=100000 else 100000
            self.js(f'window.scrollTo({x},{y})')
    
        # 元素级操作
    
        def _accord_wait(self, scanner):
            return self.waiter.until(scanner)
    
        def find_element(self, locator: Locator):
            logger.info(f'显示等待获取一个元素 => {locator}')
            return self._accord_wait(ec.presence_of_element_located(locator))
    
        def find_elements(self, locator):
            logger.info(f'显示等待获取一组元素 => {locator}')
            return self._accord_wait(ec.presence_of_all_elements_located(locator))
    
        def input(self, locator: Locator, text):
            logger.info(f'输入文本 => {locator} => {text}')
            ele = self.find_element(locator)
            ele.clear()
            ele.send_keys(text)
    
        def click(self, locator: Locator):
            logger.info(f'点击元素 => {locator}')
            self.find_element(locator).click()
    
        def text(self, locator: Locator):
            _ = self.find_element(locator).text
            logger.info(f'获取元素文本 => {locator} => {repr(_)}')
            return _
    
    
    def test():
        # 创建浏览器1
        browser1 = Browser()
        # 创建浏览器2
        browser2 = Browser()
        # 浏览器搜索
        browser.search('http://www.baidu.com')
        # 浏览器搜索
        browser.search('https://www.cnblogs.com/yufeihlf/p/5689042.html')
    
    
    if __name__ == '__main__':
        test()
    
    
  • 相关阅读:
    【Oracle】DG中 Switchover 主、备切换
    【Oracle】搭建DG(DataGuard)
    【Oracle】RAC集群中的命令
    【Oracle】RAC控制文件多路复用
    【Oracle】ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
    【Oracle】DBMS_STATS.GATHER_TABLE_STATS分析表
    【Oracle】ORA-38171: Insufficient privileges for SQL management object operation
    【Oracle】ORA-55610: Invalid DDL statement on history-tracked table
    【Oracle】三种方式查看SQL语句的执行计划
    【Oracle】ORA-01157: cannot identify/lock data file 201
  • 原文地址:https://www.cnblogs.com/bonus_scene/p/15214810.html
Copyright © 2020-2023  润新知