0


速成版-带您一天学完python自动化测试(selenium)

Selenium是一套web网站的程序自动化操作解决方案。我们通过编写自动化程序,使得自动完成浏览器界面的相关操作,除了能够自动化的完成相关操作,还能从web页面获取相关信息,然后通过程序进行分析处理,本质上就是提升从网页上输入和获取信息的能力 。

可以参考这个网站:www.byhy.net

一、selenium原理

selenium通过自动化脚本控制浏览器驱动,浏览器驱动控制浏览器,进而完成相应的自动化测试,整体来说就是程序控制。

二、selenium自动化环境搭建

2.1、pip安装

首先先下载pip,我用的mac本,在终端输入以下语句,因为后面要用该命令进行安装。

curl https://bootstrap.pypa.io/pip/get-pip.py -o get-pip.py
sudo python3 get-pip.py

安装成功,但是有warning,需要将其添加到path,将你的黄色警告的文件目录部分更换下面PATH=后的目录部分。

echo 'export PATH=/Users/hb24760/Library/Caches/pip:$PATH' >>~/.bashrc

输入指令是的文件生效,并验证pip是否安装成功。

source ~/.bashrc
pip -V

pip安装成功。

2.2、 安装Selenium客户端库

首先使用pip指令安装,在命令终端输入如下命令。

pip install selenium -i https://pypi.douban.com/simple/

安装成功,如下。

2.3、安装浏览器和浏览器驱动

浏览器首先chrome,正常下载安装就行了,这里不在赘述。

我们看一下如何安装浏览器驱动,首先看一下浏览器的版本,浏览器驱动的版本要和浏览器版本一致才可以。我的浏览器版本是114.

在下面的浏览器驱动地址中,选择114版本的chrome驱动进行安装就可以了,可以发现mac有两个版本,我是intel的,所以选上面的。

https://chromedriver.storage.googleapis.com/index.html

2.4、安装python环境与pychram集成开发环境

我是mac本,具体参考这个链接进行安装就可以了,我这边不再赘述,链接如下:

Mac安装python 环境& pycharm_mac pycharm 安装_程序员雷子的博客-CSDN博客

三、选择元素的基本方法

3.1、自动化脚本打开浏览器对应url

使用如下脚本可以自动打开chrome浏览器并打开百度的官网。

from selenium import webdriver

# 创建 WebDriver 对象,指明使用chrome浏览器驱动
# 这里现在可以指定路径,会自动寻找电脑上的chrome驱动
wd = webdriver.Chrome()

# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.baidu.com')
3.2、选择元素
3.2.1、根据元素id选择元素

首先我们看一下根据元素id属性值选择元素,根据开发规范,正常一个HTML页面的元素id是唯一的,所以根据id寻找元素是很高效的。下面是根据元素id选择元素搜索框,然后输入通讯,然后根据id选择元素按钮,点击查询。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException

# 创建 WebDriver 对象
wd = webdriver.Chrome()

# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.byhy.net/_files/stock1.html')

# 根据id选择元素,返回的就是该元素对应的WebElement对象
try:
    # 找到id为kw的元素并键入“通讯”
    element = wd.find_element(By.ID, 'kw')
    element.send_keys('通讯')
    # 通过该 WebElement对象,就可以对页面元素进行操作了
    # 比如输入字符串到 这个 输入框里 并按回车键
    # element.send_keys('通讯\n')
    # 找到id为go的按钮元素,并点击
    element = wd.find_element(By.ID, 'go')
    element.click()
except NoSuchElementException:
    print('元素id不存在!!!')

演示效果图如下:

3.2.2、根据class和tag属性选择元素

下面根据属性class和tag寻找元素,如下所示。

from selenium.common.exceptions import NoSuchElementException
from selenium import webdriver
from selenium.webdriver.common.by import By

# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome()

# WebDriver 实例对象的get方法 可以让浏览器打开指定网址
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

# 根据 class name 选择元素,返回的是 一个列表
# 里面 都是class 属性值为 animal的元素对应的 WebElement对象
try:
    elements = wd.find_elements(By.CLASS_NAME, 'animal')
    # 取出列表中的每个 WebElement对象,打印出其text属性的值
    # text属性就是该 WebElement对象对应的元素在网页中的文本内容
    for element in elements:
        print(element.text)
except NoSuchElementException:
     print("元素不存在!!!")

try:
    # wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')
    # 根据 tag name 选择元素,返回的是 一个列表
    # 里面 都是 tag 名为 div 的元素对应的 WebElement对象
    elements = wd.find_elements(By.TAG_NAME, 'div')
    # 取出列表中的每个 WebElement对象,打印出其text属性的值
    # text属性就是该 WebElement对象对应的元素在网页中的文本内容
    for element in elements:
        print(element.text)
except NoSuchElementException:
    print("元素不存在!!!")
3.2.3、隐式等待

Selenium 的 Webdriver 对象 有个方法叫

implicitly_wait

,可以称之为

隐式等待

,或者

全局等待

。该方法接受一个参数, 用来指定最大等待时长。下面通过打开网页,选择元素kw,输入通讯并回车,将查询出的id为1的元素取出来。

from selenium import webdriver
from selenium.webdriver.common.by import By

# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome()
# 设置查找不到元素等待时间
wd.implicitly_wait(10)

wd.get('https://www.byhy.net/_files/stock1.html')

element = wd.find_element(By.ID, 'kw')

element.send_keys('通讯\n')

# 返回页面 ID为1 的元素
element = wd.find_element(By.ID,'1')
3.2.4、操纵元素

我们如果想清空输入框,需要用clear方法,find_element方法可以根据属性寻找元素,get_attribute方法可以得到元素里面的属性。

from selenium import webdriver
from selenium.webdriver.common.by import By

# 创建 WebDriver 实例对象,指明使用chrome浏览器驱动
wd = webdriver.Chrome()
# 设置查找不到元素等待时间
wd.implicitly_wait(10)

wd.get('https://www.byhy.net/_files/stock1.html')

element = wd.find_element(By.ID, 'kw')

element.send_keys('通讯\n')

# 清除输入框已有的字符串
element.clear()
# 输入新字符串
element.send_keys('科技')
# 除了上面的find_elements外,也可以使用et_attribute获取元素
value = element.get_attribute('value')
element = wd.find_element(By.CLASS_NAME, 'name')
innerText = element.get_attribute('innerText')
outerHTML = element.get_attribute('outerHTML')
innerHTML = element.get_attribute('innerHTML')

print(value)
print(innerText)
print(outerHTML)
print(innerText)

四、CSS表达式

4.1、css选择器

如果我们要选择的 元素 没有id、class 属性,或者有些我们不想选择的元素 也有相同的 id、class属性值,怎么办呢?这时候我们通常可以通过

CSS selector

语法选择元素。

比如,我们想在

id 为 searchtext

的输入框中输入文本

你好。

根据class属性 选择元素的语法是在 class 值 前面加上一个点:

.class值
选择元素的直接子元素:

元素1 > 元素2 > 元素3 > 元素4

选择元素的后代元素:元素1 元素2

from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()
wd.implicitly_wait(10)

wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

# 根据CSS选择器选择id为searchtext的输入框,并键入你好
element = wd.find_element(By.CSS_SELECTOR, '#searchtext')
element.send_keys('你好')

wd.get('http://f.python3.vip/webauto/sample1.html')
# 选择id为top的非直接子元素为id是body,直接子元素class为container的
element = wd.find_element(By.CSS_SELECTOR, '#top #body > .container')
print(element.text)

当然,也可以根据通过css选择器,通过属性选择,如下所示。

from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()
wd.implicitly_wait(10)

wd.get('http://f.python3.vip/webauto/sample1.html')

# 根据属性选择元素
element = wd.find_element(By.CSS_SELECTOR, '[href="https://beian.miit.gov.cn/"]')
print(element.text)
4.2、验证css选择器

我们可以在开发者环境,验证网页的css表达式是否有效,有效的表达式,我们才写到程序里面,这样可以避免程序bug。

按住ctr+f键盘,在如下弹出的输入框输入表达式,就可以验证css选择器的表达式是否合法。

4.3、css组选择

如果我们要 同时选择所有class 为 plant

class 为 animal 的元素。怎么办?

这种情况,css选择器可以 使用

逗号

,称之为 组选择 ,像这样

.plant , .animal

选择所有 id 为 t1 里面的

span 和 p 元素

,需要写两遍#t1,如下:

#t1 > span , #t1 > p

4.4、css选择器按次序选择

我们可以指定选择的元素

是父元素的第几个子节点

,使用

nth-child,

也就是说 选择的是 第2个子元素,并且是span类型,所以这样可以这样写

span:nth-child(2)

如果你不加节点类型限制,直接这样写

:nth-child(2),

就是选择所有位置为第2个的所有元素,不管是什么类型。

也可以反过来, 选择的是父元素的

倒数第几个子节点

,使用

nth-last-child

,比如:

p:nth-last-child(1)

我们可以指定选择的元素 是父元素的第几个

某类型的

子节点,使用

nth-of-type。

还可以这样思考,选择的是

第1个span类型

的子元素,所以也可以这样写

span:nth-of-type(1)

当然也可以反过来, 选择父元素的

倒数第几个某类型

的子节点,使用

nth-last-of-type
p:nth-last-of-type(2)

如果要选择的是父元素的

偶数节点

,使用

nth-child(even)

,比如:

p:nth-child(even)

如果要选择的是父元素的

奇数节点

,使用

nth-child(odd)
p:nth-child(odd)

如果要选择的是父元素的

某类型偶数节点

,使用

nth-of-type(even)

如果要选择的是父元素的

某类型奇数节点

,使用

nth-of-type(odd)

选择 h3

后面紧跟着的兄弟节点

span。这就是一种 相邻兄弟 关系,可以这样写

h3 + span

表示元素 紧跟关系的 是

加号,

如果要选择是 选择 h3

后面所有的兄弟节点

span,可以这样写

h3 ~ span
4.5、

frame切换

我们使用switch指令可以实现frame的切入和切出,具体如下。

from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()

wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')

# 切换到frame
'''
wd.switch_to.frame('frame1')
wd.switch_to.frame('innerFrame')
'''
wd.switch_to.frame(wd.find_element(By.TAG_NAME, "iframe"))

# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements(By.CLASS_NAME, 'plant')

for element in elements:
    print(element.text)

# 再切回到html中
wd.switch_to.default_content()
# 然后再 选择操作 外部的 HTML 中 的元素
wd.find_element(By.ID,'outerbutton').click()
4.6、浏览器窗口

切换

我们依次获取 wd.window_handles 里面的所有 句柄 对象, 并且调用 wd.switch_to.window(handle) 方法,切入到每个窗口,然后检查里面该窗口对象的属性(可以是标题栏,地址栏),判断是不是我们要操作的那个窗口,如果是,就跳出循环。

因为我们一开始就在 原来的窗口里面,我们知道 进入新窗口操作完后,还要回来,可以事先 保存该老窗口的 句柄,使用如下方法。

# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle

切换到新窗口操作完后,就可以直接像下面这样,将driver对应的对象返回到原来的窗口。

#通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)

from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()
wd.implicitly_wait(10)

wd.get('https://cdn2.byhy.net/files/selenium/sample3.html')

# mainWindow变量保存当前窗口的句柄
mainWindow = wd.current_window_handle

# 点击打开新窗口的链接
link = wd.find_element(By.TAG_NAME, "a")
link.click()

for handle in wd.window_handles:
    # 先切换到该窗口
    wd.switch_to.window(handle)
    # 得到该窗口的标题栏字符串,判断是不是我们要操作的那个窗口
    if 'Bing' in wd.title:
        # 如果是,那么这时候WebDriver对象就是对应的该该窗口,正好,跳出循环,
        break

# wd.title属性是当前窗口的标题栏 文本
print(wd.title)

# 通过前面保存的老窗口的句柄,自己切换到老窗口
wd.switch_to.window(mainWindow)
4.7、mac selenium脚本启动打开已有浏览器

首先编辑~/.zshrc添加环境变量,并使其生效,终端键入:

export PATH="/Applications/Google Chrome.app/Contents/MacOS:$PATH"
source ~/.zshrc

终端执行命令打开google浏览器,如下:

Google\ Chrome --remote-debugging-port=9222 --user-data-dir="~/ChromeProfile"

我们可以先登陆好某个网站,下次就可以避免登陆校验了。

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")

browser = webdriver.Chrome(options=options)

url = 'http://fat-hms.hellobike.cn/#/resource/theme'
browser.get(url)

五、选择框

5.1、radio框

radio框选择选项,直接用WebElement的click方法,模拟用户点击就可以了。

其中

#s_radio input[name="teacher"]:checked

里面的

:checked

是CSS伪类选择

表示选择

checked

状态的元素,对

radio

checkbox

类型的input有效

# 获取当前选中的元素
element = wd.find_element(By.CSS_SELECTOR, 
  '#s_radio input[name="teacher"]:checked')
print('当前选中的是: ' + element.get_attribute('value'))

# 点选 小雷老师
wd.find_element(By.CSS_SELECTOR, 
  '#s_radio input[value="小雷老师"]').click()
5.2、checkbox框

对checkbox进行选择,也是直接用 WebElement 的 click 方法,模拟用户点击选择。

需要注意的是,要选中checkbox的一个选项,必须

先获取当前该复选框的状态

,如果该选项已经勾选了,就不能再点击。否则反而会取消选择。

我们的思路可以是这样:

  • 先把 已经选中的选项全部点击一下,确保都是未选状态
  • 再点击 要选择的
# 先把 已经选中的选项全部点击一下
elements = wd.find_elements(By.CSS_SELECTOR, 
  '#s_checkbox input[name="teacher"]:checked')

for element in elements:
    element.click()

# 再点击 小雷老师
wd.find_element(By.CSS_SELECTOR, 
  "#s_checkbox input[value='小雷老师']").click()
5.3、select选择框

对于Select 选择框, Selenium 专门提供了一个

Select类

进行操作。

对于 select单选框,操作比较简单:不管原来选的是什么,直接用Select方法选择即可。

# 导入Select类
from selenium.webdriver.support.ui import Select

# 创建Select对象
select = Select(wd.find_element(By.ID, "ss_single"))

# 通过 Select 对象选中小雷老师
select.select_by_visible_text("小雷老师")

对于select多选框,要选中某几个选项,要注意去掉原来已经选中的选项。

可以用select类 的deselect_all方法,清除所有 已经选中 的选项,然后再通过 select_by_visible_text方法 选择需要选择的。

# 导入Select类
from selenium.webdriver.support.ui import Select

# 创建Select对象
select = Select(wd.find_element(By.ID, "ss_multi"))

# 清除所有 已经选中 的选项
select.deselect_all()

# 选择小雷老师 和 小凯老师
select.select_by_visible_text("小雷老师")
select.select_by_visible_text("小凯老师")

六、Selenium实战技巧

6.1、ActionChains模拟鼠标操作

之前我们对web元素做的操作主要是:选择元素,然后 点击元素 或者 输入 字符串。除了这些写常见的操作,还有其他操作,比如 鼠标右键点击、双击、移动鼠标到某个元素、鼠标拖拽等。

这些操作,可以通过 Selenium 提供的

ActionChains

类来实现。ActionChains 类 里面提供了 一些特殊的动作的模拟,我们可以通过 ActionChains 类的代码查看到。

使用 ActionChains 来 模拟鼠标移动 操作的代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(5)

driver.get('https://www.baidu.com/')

from selenium.webdriver.common.action_chains import ActionChains

ac = ActionChains(driver)

# 鼠标移动到 元素上
ac.move_to_element(
    driver.find_element(By.CSS_SELECTOR, '[name="tj_briicon"]')
).perform()
6.2、冻结页面

有些网站上面的元素, 我们鼠标放在上面,会动态弹出一些内容。但是 当我们的鼠标 从 图标 移开, 这个 栏目就整个消失了, 就没法 查看 其对应的 HTML。

在 开发者工具栏 console 里面执行如下js代码

setTimeout(function(){debugger}, 5000)

表示在 5000毫秒后,执行 debugger 命令,执行该命令会 浏览器会进入debug状态。 debug状态有个特性, 界面被冻住, 不管我们怎么点击界面都不会触发事件。

6.3、弹出框处理
6.3.1、Alert 弹出框

Alert 弹出框,目的就是显示通知信息,只需用户看完信息后,点击 OK(确定) 就可以了。

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('https://cdn2.byhy.net/files/selenium/test4.html')

# --- alert ---
driver.find_element(By.ID, 'b1').click()

# 打印 弹出框 提示信息
print(driver.switch_to.alert.text) 

# 点击 OK 按钮
driver.switch_to.alert.accept()
6.3.2、Confirm弹出框

Confirm弹出框,主要是让用户确认是否要进行某个操作。比如:当管理员在网站上选择删除某个账号时,就可能会弹出 Confirm弹出框, 要求确认是否确定要删除。Confirm弹出框 有两个选择供用户选择,分别是 OK 和Cancel, 分别代表 确定 和 取消 操作。

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(5)

driver.get('https://cdn2.byhy.net/files/selenium/test4.html')

# --- confirm ---
driver.find_element(By.ID, 'b2').click()

# 打印 弹出框 提示信息
print(driver.switch_to.alert.text)

# 点击 OK 按钮 
driver.switch_to.alert.accept()

driver.find_element(By.ID, 'b2').click()

# 点击 取消 按钮
driver.switch_to.alert.dismiss()
6.3.3、Prompt 弹出框

出现 Prompt 弹出框 是需要用户输入一些信息,提交上去。这边的弹出框都不是HTLML,要是HTML可以直接获取元素进行操作。

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get('https://cdn2.byhy.net/files/selenium/test4.html')

# --- prompt ---
driver.find_element(By.ID, 'b3').click()

# 获取 alert 对象
alert = driver.switch_to.alert

# 打印 弹出框 提示信息
print(alert.text)

# 输入信息,并且点击 OK 按钮 提交
alert.send_keys('web自动化 - selenium')
alert.accept()

# 点击 Cancel 按钮 取消
driver.find_element(By.ID, 'b3').click()
alert = driver.switch_to.alert
alert.dismiss()

七、Xpath选择器

还有一种 灵活、强大 的选择元素的方式,就是使用

Xpath

表达式。XPath (XML Path Language) 是由国际标准化组织W3C指定的,用来在 XML 和 HTML 文档中选择节点的语言。

7.1、绝对路径选择器

从根节点开始的,到某个节点,每层都依次写下来,每层之间用

/

分隔的表达式,就是某元素的

绝对路径。

上面的xpath表达式

/html/body/div

,就是一个绝对路径的xpath表达式, 等价于 css表达式

html>body>div

自动化程序要使用Xpath来选择web元素,应该调用 WebDriver对象的方法

find_element_by_xpath

或者

find_elements_by_xpath

,像这样:

elements = driver.find_elements(By.XPATH, "/html/body/div")
7.2、相对路径选择器

我们需要选择网页中某个元素,

不管它在什么位置

。比如,选择示例页面的所有标签名为

div

的元素,如果使用css表达式,直接写一个

div

就行了。

xpath需要前面加

//

, 表示从当前节点往下寻找所有的后代元素,不管它在什么位置。所以xpath表达式,应该这样写:

//div

‘//’ 符号也可以继续加在后面,比如,要选择 所有的 div 元素里面的 所有的 p 元素 ,不管div 在什么位置,也不管p元素在div下面的什么位置,则可以这样写

//div//p

对应的自动化程序如下:

elements = driver.find_elements(By.XPATH, "//div//p")

如果使用CSS选择器,对应代码如下:

elements = driver.find_elements(By.CSS_SELECTOR,"div p")

如果,要选择 所有的 div 元素里面的 直接子节点 p , xpath,就应该这样写了

//div/p

如果使用CSS选择器,则为

div > p

通配符

如果要选择所有div节点的所有直接子节点,可以使用表达式

//div/*
*

是一个通配符,对应任意节点名的元素,等价于CSS选择器

div > *

代码如下:

elements = driver.find_elements(By.XPATH, "//div/*")
for element in elements:
    print(element.get_attribute('outerHTML'))
7.3、属性选择

Xpath 可以根据属性来选择元素。

根据属性来选择元素 是通过 这种格式来的

[@属性名='属性值']

注意:属性名注意前面有个@,属性值一定要用引号, 可以是单引号,也可以是双引号

选择 id 为 west 的元素,可以这样

//*[@id='west']

选择所有 select 元素中 class为 single_choice 的元素,可以这样

//select[@class='single_choice']​​​​​​​

同样的道理,我们也可以利用其它的属性选择

比如选择 具有multiple属性的所有页面元素 ,可以这样

//*[@multiple]

要选择 style属性值 包含 color 字符串的 页面元素 ,可以这样

//*[contains(@style,'color')]

要选择 style属性值 以 color 字符串

开头

的 页面元素 ,可以这样

//*[starts-with(@style,'color')]
7.4、按次序选择

和CSS选择器类似,具体参考这个网站:Xpath选择器 | 白月黑羽

7.5、组选择、父节点、兄弟节点

和CSS选择器类似,具体参考这个网站:Xpath选择器 | 白月黑羽

标签: 学习 python selenium

本文转载自: https://blog.csdn.net/nuist_NJUPT/article/details/131691877
版权归原作者 nuist__NJUPT 所有, 如有侵权,请联系我们删除。

“速成版-带您一天学完python自动化测试(selenium)”的评论:

还没有评论