selenium笔记

1. 历史

2004年selenium诞生 seleniumRC js命令
2006年webdriver诞生
2008年selenium与webdriver合并selenium2.0
2016年selenium3.0诞生
2021年selenium4.0诞生
selenium4 统一了各浏览器标准,应该是未来5年内的主流
必须3.7以上,安装报错,多半要升级pip: python -m pip install --upgrade pip

2. 工作原理

  • c/s架构,客户端和服务器 通过http请求交换信息 (selenium/webdriver/remote/remote_connection.py 里的_request())
  • 通过chromedriver控制浏览器 http://chromedriver.storage.googleapis.com/index.html /usr/local/bin 或项目根目录 或windows的python根目录。
  • 每次都有一个对话session和唯一标识 sessionID

3. 常用命令

  • driver.get() 打开浏览器进入指定url ###########################
  • close和quit 的进程影响
  • .get_cookies() 获取全部cookie
  • .get_cookie(‘具体名字’) 根据cookie的name查找具体
  • .add_cookie() 增加一个cookie
  • .delete_all_cookies 删除全部cookie
  • delete_cookie(“cookie_name”) 删除指定cookie
  • driver.find_element() 定位 (from selenium.webdriver.common.by import By)
  • .get_attribute() 获取元素属性
  • .forward() 向前
  • .back() 后退
  • .refresh() 刷新
  • .title 获取页面标题
  • .get_screenshot_as_file(图片名) 截图
  • .maximize_window() 窗口最大化
  • .set_window_size(900, 700) 固定窗口大小
  • drvier.name 获取浏览器名 ###########################
  • .get_window_position 获取当前窗口坐标
  • .get_window_size 获取当前窗口长宽
  • 元素.location 获取元素
  • .size 元素大小
  • .is_selected() 是否选中
  • .is_displayed() 是否显示
  • .is_enabled() 是否禁用
  • .text 获取本文
  • .send_keys(u’青春’) 输入
  • .clear() 清空
  • .click() 点击
  • .tag_name 元素标签名
  • .value_of_css_property(css_name) 获取css属性值
  • .sumbit() 提交表单 ###########################

4. 等待

  • 隐式
    driver.implicitly_wait(10)
  • 程序睡眠、强制等待
    times.sleep(5)
  • 显式
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    element = WebDriverWait(driver, 4, 0.5).until(EC.presence_of_element_located((By.ID, “kw”))) #也有until_not
<div id="d">
    <button id="kw">我是按钮</button>
</div>
<script>
    setTimeout( ()=>{
        var k = document.getElementById('kw')
        k.remove()
    }
    ,3000
)
</script>
  • 过期终止 ##################
    driver.set_page_load_timeout(5)
try:
    driver.get("")
except:
    driver.execute_script("window.stop()")

5. 定位元素

  • 单个或多个
  • ID
  • LINK_TEXT
  • PARTIAL_LINK_TEXT
  • NAME
  • TAG_NAME
  • CLASS_NAME
  • CSS_SELECTOR 大多数情况下都是在浏览器f12直接复制
    driver.find_element(By.CSS_SELECTOR, ‘.a.b.c[value=“”]’)
    用来表示id属性
    小数点用来表示class属性
    []万能属性可以用来表示所有属性:[id=“”] [class=“”]
    如果用的标签名就不要在前面加任何符号 如 input[class=“”]

用来表示父子元素之间的关系 如 div > a
空格表示祖先和子孙之间的关系 如 div#id a.class ###########################

索引法
a:nth-child(3) 索引法,第几个
a:first-child 第一个
a:last-child 第二个

获取目标索引的元素,且必须为a标签或其他指定筛选
获取符合条件的所有元素
如果前面没有父级或祖级,则会获取全页面所有块级内符合元素

  • XPATH 大多数情况下都是在浏览器f12直接复制
    一般定位
    /div/a[1] div下的第一个a
    /div/a[last()] div下的最后一个a
    /div/a[last()-1] div下倒数第二个a
    /div/a[position()<4] 选取div下最前面的3个a
    /div[@name] 选取有name属性的div
    /div[@name=“kw”] 选取name为kw的div
    /div/a[price>50] 选取div下价格大于50的a
    绝对定位/ 和相对定位// :相对定位时,系统最优为最末尾标签名在最上的 ######################

文本定位 如 //button[text()=“”]
模糊定位 [starts-with(@id,“s”)] 或 [ends-with(@id,“e”)]
[图片]
逻辑定位and or: //input[@name=“phone” and @name=“email”] ####################

轴定位: 轴名称::节点名称
当前节点后所有节点 //a[@…=“”]/following:😗
当前节点后同级节点 //a[@…=“”]/following-sibling:😗
当前节点所有子节点 //a[@…=“”]/child:😗
当前节点前所有节点 //a[@…=“”]/preceding:😗
当前节点前同级节点 //a[@…=“”]/preceding-sibling:😗
当前节点所有父节点 //a[@…=“”]/parent:😗
当前节点所有祖父节点 //a[@…=“”]/ancestor:😗
###########################
相对定位:

from selenium.webdriver.support.relative_locator import locate_with, with_tag_name

above 元素上
below 元素下
to_left_Of 元素左
to_right_Of 元素右
near 附近

e2 = driver.find_element(locate_with(By.TAG_NAME, "xxxxx").above(e1).to_left_of(e1))

############################
通配符
[图片]
比如 //查找所有元素节点
比如 //
[@id] 即查找任何带有id属性的节点
比如 //node()/a 查找各种子元素有a的元素的子元素a
多路径匹配://button | //a

6. 复杂情况

  • js改变元素属性
js = 'var q=document.getElementById(\"idddd\");q.style.xxx=(\"xxxx\");'
driver.execute_script(js)
  • 元素被遮挡
  • 元素要特定触发
  • 下拉框
from selenium.webdriver.support.ui import Select 
select_by_index()           # 通过索引定位;注意:>index索引是从“0”开始。
select_by_value()           # 通过value值定位,va>lue标签的属性值。
select_by_visible_text()    # 通过文本值定位,即显>示在下拉框的值。
Select(chr.find_element_by_name("姓名")).select_by_index(1) ###############
  • alert弹窗
    driver.switch_to.alert.text
    driver.switch_to.alert.accept()
  • 内嵌frame
    switch_to.frame()
    driver.switch_to.parent_frame()
  • 多标签页
    current_window_handle:获取当前窗口的句柄
    window_handles:返回当前浏览器的所有窗口的句柄
    switch_to_window():用于切换到对应的窗口
  • 滚动条
    js = “var q=document.documentElement.scrollTop=1200”
  • 内嵌滚动条
    用内部顶层元素拖拽到底部
    document.getElementById(‘kw1’).scrollTop=1200

7. 鼠标操作

from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).具体动作(值或元素).perform() 
- click_and_hold()  :点击鼠标左键,不松开  (不写元素也不报错)
- context_click() :点击鼠标右键 (不写元素也不报错)
- double_click() :双击鼠标左键  (不写元素也不报错)
- drag_and_drop(起始元素, 目标元素) :拖拽到某个元素然后松开 
- drag_and_drop_by_offset(起始元素, xoffset, yoffset)  :拖拽到某个坐标然后松开(如果坐标过大,会引发报错)
- move_by_offset(xoffset, yoffset) :鼠标从当前位置移动到某个坐标 ( 如果坐标过大,会引发报错)
- move_to_element(目标元素)  :鼠标移动到某个元素 (如果元素不存在则报错,如果存在但遮挡则不报错)
- release() :释放按住的鼠标  ,(如果之前并未点击鼠标,也不会报错)

8. 键盘操作

 from selenium.webdriver.common.keys import Keys
- 常见按钮,更多按键可以在Keys.py查看。
(Keys.CONTROL , 'a') 全选
(Keys.CONTROL , 'c') 赋值
(Keys.CONTROL , 'x') 剪切
(Keys.CONTROL , 'v') 粘贴
(Keys.F1) F1-F12
(Keys.BACK_SPACE) 删除键
(Keys.ENTER) 回车
(Keys.ESCAPE) esc键
(Keys.SPACE)  空格
(Keys.TAB) tab制表键
  • 单独用法
 ActionChains(driver).send_keys(Keys.ENTER).perform()
ActionChains(driver).send_keys_to_element(el,Keys.ENTER).perform()
driver.find_element_by_id("kw").send_keys(Keys.ENTER') 
  • 组合用法
 driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')    
  • 连续用法
ActionChains(driver).send_keys(Keys.TAB).send_keys(Keys.ENTER).perform() 
pause(5) 是中间暂停5秒

10. 自定义设置

具体在 options.py

  • 添加启动参数
options = webdriver.ChromeOptions()
options.add_argument("具体参数")
driver = webdriver.Chrome(options=options)
无头模式 options.add_argument("headless")
屏幕分辨率(要和无头模式一起使用为佳) options.add_argument('window-size=1920x1670')  
不加载任何图 options.add_argument("blink-settings=imagesEnabled=false")
最大化启动:options.add_argument("--start-maximized")
代理(伪装手机)option.add_argument('--user-agent=iphone')
用户配置: user-data-dir= (通过浏览器输入chrome://version/打开后看个人资料路径即可拿到,注意,mac需要删到Google/Chrome,并且需要关闭目前谷歌的本地浏览器)
设置驱动路径  
from selenium.webdriver.chrome.service import Service as ChromeService
service = ChromeService(executable_path=你的driver路径)  
driver = webdriver.Chrome(service=service)



续session 启动(调试写脚本神器):

  • 原理:手动打开一个浏览器,需要指定浏览器的端口,所以你就不能通过点击图标的方式启动,要用命令的方式启动,因为这样可以加端口参数。然后你的所有自动化脚本,全部设置调试域名为这个手动命令启动的浏览器端口。脚本就会自动接着这个浏览器启动。
  • 多线程共同作用
    接着浏览器启动自动化 (请先用对应端口手动启动浏览器 --remote-debugging-port=6789 )
from selenium import webdriver
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option("debuggerAddress", "127.0.0.1:6789")
driver = webdriver.Chrome(options=options)
driver.find_element(By.ID,'kw1').send_keys('x')
driver.quit()

数据分离&关键字驱动&闭包动态: (比较常见)

  • 媒介:使用excel工作簿,是多维度的
    excel表后缀xls的读:xlrd (pip3 install xlrd)
sz=xlrd.open_workbook(fname).sheet_by_index(0) #打开一个工作簿,并用下标获取里面的第一个工作表,
sz=xlrd.open_workbook(fname).sheet_by_name("Sheet1") #打开一个工作簿,并用名称获取里面的某一个工作表
sz.cell_value(1,1)#读取单元格内容
sz._cell_values # 直接拿到二元元组 所有数据
sz.nrows #读取行数
sz.ncols #读取列数
sz.name #读取工作表名字
sz.number # 工作表序号 0开始
  • 单数据分离:相较于线性脚本,数据拿出,动态结合。
    封装到ttt.py
import xlrd
class XLS():
    def __init__(self,fname,index):
        self.fname = fname
        self.biao = xlrd.open_workbook(fname).sheet_by_index(index)

    def get_all_values(self):
        return self.biao._cell_values

    def get_value(self,y,x):
        return self.biao.cell_value(y,x)
        
 test.py:
from selenium import webdriver
import time
from selenium.webdriver.common.by import By

from ttt import XLS
xls = XLS('aaa.xls',0)

driver = webdriver.Chrome()
driver.get('http://localhost:63342/7thProject/wqrf.html')

inputs = driver.find_elements(By.TAG_NAME,'input')

for i in range(len(inputs)):
    # i = 0,1,2,3,4,5,6...11
    # 行 = 0,0,0,1,1,1   除3取整
    # 列 = 0,1,2,0,1,2  除3取余
    inputs[i].send_keys(   xls.get_value(int(i/3),int(i%3))  )

time.sleep(5)
driver.quit()

数据分离+关键字驱动:增加了元素的具体动作和driver的一些常用功能

class PLAY():
    # 第一部分:元素的定位。第二部分:元素的动作。第三部分:接收excel表数据并格式化
    输入框 = "driver.find_element(By.ID,'kw1')"
    按钮 = "driver.find_element(By.ID,'kw2')"
    弹窗 = "driver.switch_to.alert"
    def __init__(self,元素字符串,值字符串):
        self.元素= eval(eval( 'PLAY.%s'%元素字符串 ))
        self.值 = 值字符串

    def 输入(self):
        self.元素.clear()
        self.元素.send_keys(self.值)
    def 点击(self):
        self.元素.click()
    def 断言(self):
        assert self.元素.text == self.值
        self.元素.accept()


all_cells = xls.get_all_values() #二维列表
for i in all_cells:
    play = PLAY(i[0],i[2])
    exec('play.%s()'%i[1])
    time.sleep(1)

数据分离+关键字驱动+unittest闭包动态:

from selenium import webdriver
import time
import unittest
from selenium.webdriver.common.by import By
from ttt import XLS
xls = XLS('aaa.xls',0)
driver = webdriver.Chrome()
driver.get('http://localhost:63342/7thProject/wqrf.html')
class PLAY():
    # 第一部分:元素的定位。第二部分:元素的动作。第三部分:接收excel表数据并格式化
    输入框 = "driver.find_element(By.ID,'kw1')"
    按钮 = "driver.find_element(By.ID,'kw2')"
    弹窗 = "driver.switch_to.alert"
    def __init__(self,元素字符串,值字符串):
        self.元素= eval(eval( 'PLAY.%s'%元素字符串 ))
        self.值 = 值字符串
    def 输入(self):
        self.元素.clear()
        self.元素.send_keys(self.值)
    def 点击(self):
        self.元素.click()
    def 断言(self):
        assert self.元素.text == self.值
        self.元素.accept()
class TEST(unittest.TestCase):
    def template(self,i):
        play = PLAY(i[0], i[2])
        exec('play.%s()'%i[1])
        time.sleep(2)
def demo(i):
    def func(self):
        TEST.template(self,i)
    return func
all_cells = xls.get_all_values() #二维列表
for i in range(len(all_cells)):
    setattr(TEST,'test_%04d'%i,demo(all_cells[i]))
unittest.main()
time.sleep(3)
driver.quit()

关键字封装

弹窗处理:弹窗断言 + 弹窗关闭
句柄切换:值为下标
页面操作:关闭,前进,后退。
鼠标: 值为具体操作
键盘:值为具体操作

from selenium import webdriver
import time
import unittest
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import  ActionChains
from selenium.webdriver.common.by import By
from ttt import XLS
xls = XLS('aaa.xls',0)

driver = webdriver.Chrome()
driver.get('http://localhost:63342/7thProject/wqrf.html')
# #
class PLAY():
    # 第一部分:元素的定位。第二部分:元素的动作。第三部分:接收excel表数据并格式化
    输入框 = "driver.find_element(By.ID,'kw1')"
    按钮 = "driver.find_element(By.ID,'kw2')"
    超链接 = "driver.find_element(By.ID,'kw3')"
    def __init__(self,元素字符串,值字符串):
        if 元素字符串:
            self.元素= eval(eval( 'PLAY.%s'%元素字符串 ))
        self.值 = 值字符串
    def 输入(self):
        self.元素.clear()
        self.元素.send_keys(self.值)
    def 点击(self):
        self.元素.click()
    def 弹窗断言(self):
        assert driver.switch_to.alert.text == self.值
        driver.switch_to.alert.accept()
    def 句柄跳转(self):
        driver.switch_to.window(driver.window_handles[-1])
    def 页面操作(self):
        if self.值 == '关闭':
            driver.close()
        elif self.值 == '向前':
            driver.forward()
        elif self.值 == '向后':
            driver.back()
    def 鼠标(self):
        if self.值 == '右键':
            ActionChains(driver).context_click().perform()

    def 键盘(self):
        if '粘贴' == self.值.split('-')[1]:
            元素 = eval(eval( 'PLAY.%s'%(self.值.split('-')[0]) ))
            元素.send_keys(Keys.COMMAND , 'v')

class TEST(unittest.TestCase):
    def template(self,i):
        play = PLAY(i[0], i[2])
        exec('play.%s()'%i[1])
        time.sleep(1)

    @classmethod
    def tearDownClass(cls) -> None:
        time.sleep(4)
        driver.quit()

def demo(i):
    def func(self):
        TEST.template(self,i)
    return func

all_cells = xls.get_all_values() #二维列表

for i in range(len(all_cells)):
    setattr(TEST,'test_%04d'%i,demo(all_cells[i]))


unittest.main()

po模式:

from selenium import webdriver
import time
import unittest
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import  ActionChains
from selenium.webdriver.common.by import By
from ttt import XLS
from ttt import GET_ELEMENT
xls = XLS('aaa.xls',0)
get_element = GET_ELEMENT()
driver = webdriver.Chrome()
driver.get('http://localhost:63342/7thProject/wqrf.html')

class PLAY():
    def __init__(self,页面字符串,元素字符串,值字符串):
        if 元素字符串:
            self.元素= eval(eval( 'get_element.%s("%s")'%(页面字符串,元素字符串)  ))
        self.值 = 值字符串
    def 输入(self):
        self.元素.clear()
        self.元素.send_keys(self.值)
    def 点击(self):
        self.元素.click()
    def 弹窗断言(self):
        assert driver.switch_to.alert.text == self.值
        driver.switch_to.alert.accept()
    def 句柄跳转(self):
        driver.switch_to.window(driver.window_handles[-1])
    def 页面操作(self):
        if self.值 == '关闭':
            driver.close()
        elif self.值 == '向前':
            driver.forward()
        elif self.值 == '向后':
            driver.back()
    def 鼠标(self):
        if self.值 == '右键':
            ActionChains(driver).context_click().perform()

    def 键盘(self): # 首页-输入框-粘贴
        if '粘贴' == self.值.split('-')[-1]:
            元素 = eval(eval( 'get_element.%s("%s")'%(self.值.split('-')[0],self.值.split('-')[1])  ))
            元素.send_keys(Keys.COMMAND , 'v')

class TEST(unittest.TestCase):
    def template(self,i):
        play = PLAY(i[0],i[1], i[3])
        exec('play.%s()'%i[2])
        time.sleep(1)

    @classmethod
    def tearDownClass(cls) -> None:
        time.sleep(4)
        driver.quit()

def demo(i):
    def func(self):
        TEST.template(self,i)
    return func

all_cells = xls.get_all_values() #二维列表

for i in range(len(all_cells)):
    setattr(TEST,'test_%04d'%i,demo(all_cells[i]))


unittest.main()
import xlrd
class XLS():
    def __init__(self,fname,index):
        self.fname = fname
        self.biao = xlrd.open_workbook(fname).sheet_by_index(index)

    def get_all_values(self):
        return self.biao._cell_values[1:]

    def get_value(self,y,x):
        return self.biao.cell_value(y,x)

    def get_col(self):
        return self.biao.ncols

    def get_row(self):
        return self.biao.nrows


class GET_ELEMENT():
    def 首页(self,s):
        d = {
            "输入框" : "driver.find_element(By.ID,'kw1')",
            "按钮" : "driver.find_element(By.ID,'kw2')",
            "超链接" : "driver.find_element(By.ID,'kw3')",
        }
        return d[s]
    def 第二页(self,s):
        d = {
            "输入框" : "driver.find_element(By.ID,'kw2-1')",
            "按钮" : "driver.find_element(By.ID,'kw2-2')",
        }
        return d[s]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值