1、之前已经发过两次使用单浏览器了,但是这个最完美,此篇并没有使用任何单例模式的设计模式,用了实例属性结果缓存到类属性。

2、最简单的控制单浏览器是只实例化一次类,然后一直使用这个对象,但每个地方运行前必须确保先调用实例化的那段代码,这在多个测试方法之间没有依赖关系时候,并不需要指定先在什么地方实例化。使用一些方法控制,这可以在任何地方实例化无数次都没问题,比判断全局变量为空则实例化弹出浏览器这种方法好用很多。因为此种方法高度封装后,不会在其他类外地方要写代码控制了,在任何地方实例化浏览器都是一样的写法,具有高度的统一性。此类并不是用了单例模式,就算用不用此类,控制一个浏览器不是需要使用什么单例模式,只需要控制driver属性在任何实例中是同一个对象就可以了。

3、如果要使用单例模式来保证那个slenium使之只有一个浏览器,则要小心一个地方,常规型的python3中重写__new__,只能保证每个实例是指向同一个对象,并不能保证只调用__init__一次,需要处理下, 参考

python单例模式控制成只初始化一次,常规型的python单例模式在新式类和经典类中的区别。

放出这个类,用法见测试用例。

 1、基于selenium的二次包装,整体代码非常短易于理解,带有两个自定义方法示例供参考,易于扩展。
2、支持无限实例化此类,只要曾经弹出了浏览器,在任何跨函数 跨类 跨python文件中再次实例化此类,绝对不会弹第二个浏览器。所有地方无论怎么写,仍然保持使用同一个浏览器窗口。(当然指的是单次运行python文件,如果自己反复的关闭和启动python,那肯定是不能使用已打开的浏览器的)
3、支持使用自定义的方法名字,同时全所未有的支持了直接性的使用所有此类中没有定义的方法,但在官方类中有的api方法,比如直接支持DriverWrapper().execute_script(script, *args)这种写法。
4、其余想自定义名称的方法可以在这个类下面接着写或者继承这个类再添加其他更多方法
5、支持了一个控制台日志,精确 到文件的名字 类名 是在哪一行打印的日志。 经过测试,支持python2和3,支持chrom和firefox,需要安装selenium包和浏览器驱动放到有环境变量的文件夹下。然后就能运行了。
# coding:utf-8

import logging
import unittest
from selenium import webdriver class cached_class_property(object):
def __init__(self, func):
self.func = func def __get__(self, obj, cls):
if obj is None:
return self
value = self.func(obj)
setattr(cls, self.func.__name__, value)
return value class DriverWrapper():
"""
1、基于selenium的二次封装,
2、支持无限实例化此类,仍然保持使用同一个浏览器窗口。
3、支持使用自定义的方法名字,同时直接性的支持使用所有此类中没有定义的方法,但在官方类中有的api方法,比如直接支持DriverWrapper().execute_script(script, *args)这种写法。
4、其余想自定义名称的方法可以在这个类下面接着写或者继承这个类再添加其他更多方法
""" def __init__(self, driver_name):
"""
:param driver_name: 浏览器名字数字或者字母
"""
self.driver_name = driver_name @cached_class_property
def driver(self):
driver_var = None
if self.driver_name in ['chrome', 1]:
driver_var = webdriver.Chrome()
if self.driver_name in ['firefox', 2]:
driver_var = webdriver.Chrome()
return driver_var @cached_class_property
def logger(self):
logger_var = logging.getLogger(self.__class__.__name__)
logger_var.setLevel(logging.DEBUG)
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(filename)s - %(lineno)d - %(levelname)s - %(message)s', "%Y-%m-%d %H:%M:%S"))
logger_var.addHandler(stream_handler)
return logger_var def open(self, url):
self.driver.get(url) def find_element_by_css_selector(self, css_str): # 使用自定义的方法覆盖了原方法,比如先打印出一段话
self.logger.debug('要查找的元素的css选择器是 --> ' + css_str)
self.driver.find_element_by_css_selector(css_str) def __getattr__(self, item): # 想把其他的webdriver的操作方法直接添加进来,不一个一个的再写一个方法然后调用driver属性的方法,不想一直搞冗余的代码,可以这么做。python先使用__getattribute__,查不到才会调用__getsttr__方法,利用这个特性,来实现这个添加driver的属性到自己类里面
return getattr(self.driver, item) class _Test(unittest.TestCase):
def test(self):
driver_wrapper = DriverWrapper(1)
driver_wrapper.open('https://www.baidu.com') # 有人不喜欢用get,可以叫open什么的
driver_wrapper.find_element_by_css_selector('#kw') # 当类中存在方法,优先使用了自己类里面的方法,所以每次使用css选择器查找元素时候会打印一个日志
driver_wrapper.find_element_by_id('kw') # 当类中不存在此方法,使用Chrome类的方法 driver_wrapper2 = DriverWrapper(1) # 重新实例化一次这个类,仍然可以接着使用之前的浏览器,不会重新弹一个浏览器窗口
driver_wrapper2.get('https://www.sina.com') # 仍然可以使用get方法打开页面
driver_wrapper.logger.info('运行完了,现在想关闭浏览器')
driver_wrapper2.driver.close() # 这样做也可以,但不算是动态添加属性了,这是直接使用的该实例的driver属性的方法,driver属性是Chrome的一个实例。 if __name__ == '__main__':
unittest.main()

史上最强大的python selenium webdriver的包装的更多相关文章

  1. Python+Selenium+webdriver环境搭建(windows)以及相关资源下载链接

    今天记录一下测试小菜鸟alter在测试入门的一点关于python+Selenium+webdriver环境搭建的经历以及资源分享.欢迎交流学习,批评指正. 一.Python的下载与安装 1.pytho ...

  2. Python Selenium Webdriver常用方法总结

    Python Selenium Webdriver常用方法总结 常用方法函数 加载浏览器驱动: webdriver.Firefox() 打开页面:get() 关闭浏览器:quit() 最大化窗口: m ...

  3. python selenium webdriver入门基本操作

    python selenium webdriver入门基本操作 未经作者允许,禁止转载! from selenium import webdriver import time driver=webdr ...

  4. 强烈推荐:Android史上最强大的自定义任务软件Tasker

    强烈推荐:Android史上最强大的自定义任务软件Taskerhttp://bbs.mumayi.com/thread-28387-1-1.html(出处: 木蚂蚁手机乐园) Android上的Tas ...

  5. Python+Selenium WebDriver API:浏览器及元素的常用函数及变量整理总结

    由于网页自动化要操作浏览器以及浏览器页面元素,这里笔者就将浏览器及页面元素常用的函数及变量整理总结一下,以供读者在编写网页自动化测试时查阅. from selenium import webdrive ...

  6. 史上最全!Selenium元素定位的30种方式

    Selenium对网页的控制是基于各种前端元素的,在使用过程中,对于元素的定位是基础,只有准去抓取到对应元素才能进行后续的自动化控制,我在这里将对各种元素定位方式进行总结归纳一下. 这里将统一使用百度 ...

  7. windows操作系统python selenium webdriver安装

    这几天想搞一个爬虫,就来学习一下selenium,在网上遇见各种坑,特写一篇博文分享一下selenium webdriver的安装过程. 一.安装selenium包 pip install selen ...

  8. Python + Selenium WebDriver Api 知识回顾

    一直再用 Selenium WebDriver 但是用的都比较零散,也没有做过总结,今天借此机会,整理一下,方便大家使用时查阅 webDriver  的属性 ['CONTEXT_CHROME', 'C ...

  9. Linux环境下搭建python+selenium+webdriver环境

    1.下载并安装python,一般安装linux系统,自带有python,则python不用安装.要下载可以在官网上下载: 或者使用下面命令安装: sudo apt-get install python ...

随机推荐

  1. drupal 精彩文章

    1.如何快速查找Drupal表单的Form ID?http://www.drupalla.com/node/2306

  2. 将windows控制台内容输出到文件中

    将windows控制台内容输出到文件中 dir>c:/file.txt 2>&1   对应的java  class   >c:/file.txt 2>&1   ...

  3. oracle的启动和停用

    1.开始-运行-cmd-确定 2.cmd页面,输入set ORACLE_SID=(你的数据库实例名),回车,执行 3.继续输入‘sqlplus/nolog’,敲击回车键 4.sql输入栏,输入‘con ...

  4. Qt添加驱动——Qt数据库之添加MySQL驱动插件

    Qt数据库之添加MySQL驱动插件(1) 现在可用的数据库驱动只有3种,在Qt中,我们需要自己编译其他数据库驱动的代码,让它们以插件的形式来使用.下面我们就以现在比较流行的MySQL数据库为例,说明一 ...

  5. 编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127)。不在范围内的不作统计。

    题目描述 编写一个函数,计算字符串中含有的不同字符的个数.字符在ACSII码范围内(0~127).不在范围内的不作统计. 输入描述: 输入N个字符,字符在ACSII码范围内. 输出描述: 输出范围在( ...

  6. QMDP-Net: Deep Learning for Planning under Partial Observability

    一篇用deep neural network做POMDP的论文

  7. (笔记)Mysql命令grant on:增加新用户并控制其权限

    grant on命令用于增加新用户并控制其权限. grant on命令格式:grant select on 数据库.* to 用户名@登录主机 identified by “密码”; 1) 增加一个用 ...

  8. 高通 fastboot 显示

    需要在fastboot里面添加功能用于保存,记录一下fastboot显示的过程. android O新添加了选项,如下 platform/msm_shared/rules.mk ifeq ($(ENA ...

  9. linux系统下的缺失 libstdc++.so.6: version’GLIBCXX_3.4.20’的问题:

    在linux下遇到了一个这样的问题,使用anaconda时,它的安装库里的文件被提示:缺失 libstdc++.so.6: version’GLIBCXX_3.4.20’.后来经过查看资料知道了原来是 ...

  10. Linux操作_磁盘管理_增加虚拟磁盘

    环境:虚拟机 VM 12,Linux版本号 CentOS 7.3 1,在当前的虚拟机选项卡点击鼠标右键,选择“设置” 2,在弹出的对话框中左侧选中“磁盘”->点击下方“添加”按钮,在弹出的“添加 ...