Selenium的基本使用

文章目录

引入

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

# 打开Chome浏览器
wd = webdriver.Chrome()

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

# 关闭浏览器
wd.quit()

一.选择元素的基本方法

1.根据id 选择元素

python 复制代码
# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element(By.ID, 'kw')

# 通过该 WebElement对象,就可以对页面元素进行操作了
# 比如输入字符串到 这个 输入框里
element.send_keys('通讯\n')

2.根据 class属性选择元素

举例:

html 复制代码
<body> 
        <div class="plant"><span>土豆</span></div>
        <div class="plant"><span>洋葱</span></div>
        <div class="plant"><span>白菜</span></div>

        <div class="animal"><span>狮子</span></div>
        <div class="animal"><span>老虎</span></div>
        <div class="animal"><span>山羊</span></div>

</body>

如果我们要选择 所有的 动物, 就像下面可以这样写

【注意element后面多了个s】

py 复制代码
wd.find_elements(By.CLASS_NAME, 'animal')

当元素有 多个class类型 时

html 复制代码
<span class="chinese student">张三</span>

我们要用代码选择这个元素,可以指定任意一个class 属性值,都可以选择到这个元素,如下

py 复制代码
element = wd.find_elements(By.CLASS_NAME,'chinese')

或者

py 复制代码
element = wd.find_elements(By.CLASS_NAME,'student')

而不能这样写

py 复制代码
element = wd.find_elements(By.CLASS_NAME,'chinese student')

3.根据 tag名 选择元素

类似的,我们可以通过指定 参数为 By.TAG_NAME ,选择所有的tag名为 div的元素,如下所示

py 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()

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)

4.通过WebElement对象选择元素

WebElement对象 也可以调用 find_elementsfind_element 之类的方法。

WebDriver 对象 选择元素的范围是 整个 web页面, 而WebElement 对象 选择元素的范围是 该元素的内部。

py 复制代码
element = wd.find_element(By.ID,'container')

# 限制 选择元素的范围是 id 为 container 元素的内部。
spans = element.find_elements(By.TAG_NAME, 'span')
for span in spans:
    print(span.text)

5.find_element 和 find_elements 的区别

使用 find_elements 选择的是符合条件的 所有 元素, 如果没有符合条件的元素, 返回空列表

使用 find_element 选择的是符合条件的 第一个 元素, 如果没有符合条件的元素, 抛出 NoSuchElementException 异常

二.等待界面元素出现

在我们进行网页操作的时候, 有的元素内容不是可以立即出现的, 可能会等待一段时间,这时候找不到元素就会报错。

py 复制代码
import time
while True:
    try:
        element = wd.find_element(By.ID,'1')
        print(element.text)
        break
    except:
        time.sleep(1)

Selenium提供了一个更合理的解决方案,是这样的:

当发现元素没有找到的时候, 并不立即返回 找不到元素的错误。

而是周期性(每隔半秒钟)重新寻找该元素,直到该元素找到,

或者超出指定最大等待时长,这时才 抛出异常(如果是 find_elements 之类的方法, 则是返回空列表)。

1.隐式等待

Selenium 的 Webdriver 对象 有个方法叫 implicitly_wait ,可以称之为 隐式等待 ,或者 全局等待

该方法接受一个参数, 用来指定 最大等待时长。

如果我们 加入如下代码

py 复制代码
wd.implicitly_wait(10)

那么后续所有的 find_element 或者 find_elements 之类的方法调用 都会采用上面的策略:

如果找不到元素, 每隔 半秒钟 再去界面上查看一次, 直到找到该元素, 或者 过了10秒 最大时长。

完整案例如下

py 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

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')

print(element.text)

2.显示等待

如果某个控件比较特殊,需要更长的时间加载,比如十几秒或者更长,就可以使用显示等待对其进行单独处理。

WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)

  • driver:浏览器驱动

  • timeout:最长超时时间,默认以秒为单位

  • poll_frequency:检测的间隔步长,默认为0.5s

  • ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementExeception异常。

需要引入

python 复制代码
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait()中的until()和until_not()

python 复制代码
#调用该方法提供的驱动程序作为参数,直到返回值为True
WebDriverWait(driver,10).until(method,message="")
#调用该方法提供的驱动程序作为参数,直到返回值为False
WebDriverWait(driver,10).until_not(method,message="")

until是当某元素出现或什么条件成立则继续执行,

until_not是当某元素消失或什么条件不成立则继续执行,参数也相同。

实例:等待图片元素加载完成再进行点击关闭操作

python 复制代码
    wait = WebDriverWait(driver, 20)
    element = wait.until(EC.visibility_of_element_located((By.XPATH, '//img[@src="https://static.cdninstagram.com/rsrc.php/v3/yb/r/sHkePOqEDPz.gif"]')))
    time.sleep(1)
    driver.find_element(by=By.CSS_SELECTOR, value='svg[aria-label="Close"]').click()

三.操控元素的基本方法

操控元素通常包括

  • 点击元素
  • 在元素中输入字符串,通常是对输入框这样的元素
  • 获取元素包含的信息,比如文本内容,元素的属性

1.点击元素

当我们调用 WebElement 对象的 click 方法去点击 元素的时候, 浏览器接收到自动化命令,点击的是该元素的 中心点 位置 。

2.输入框

py 复制代码
element = wd.find_element(By.ID, "input1")

element.clear() # 清除输入框已有的字符串
element.send_keys('alkaid') # 输入新字符串

3.获取元素信息

(1)获取元素的文本内容

通过WebElement对象的 text 属性,可以获取元素 展示在界面上的 文本内容。

比如

py 复制代码
element = wd.find_element(By.ID, 'animal')
print(element.text)

(2)获取元素属性

通过WebElement对象的 get_attribute 方法来获取元素的属性值

比如要获取元素属性class的值,就可以使用 element.get_attribute('class')

如下:

py 复制代码
element = wd.find_element(By.ID, 'input_name')
print(element.get_attribute('class'))

(3)获取整个元素对应的HTML

要获取整个元素对应的HTML文本内容,可以使用 element.get_attribute('outerHTML')

如果,只是想获取某个元素 内部 的HTML文本内容,可以使用 element.get_attribute('innerHTML')

(4)获取输入框里面的文字

对于input输入框的元素,要获取里面的输入文本,用text属性是不行的,这时可以使用 element.get_attribute('value')

比如

py 复制代码
element = wd.find_element(By.ID, "input1")
print(element.get_attribute('value')) # 获取输入框中的文本

(5)获取元素文本内容2

通过WebElement对象的 text 属性,可以获取元素 展示在界面上的 文本内容。

但是,有时候,元素的文本内容没有展示在界面上,或者没有完全完全展示在界面上。 这时,用WebElement对象的text属性,获取文本内容,就会有问题。

出现这种情况,可以尝试使用 element.get_attribute('innerText') ,或者 element.get_attribute('textContent')

使用 innerText 和 textContent 的区别是,前者只显示元素可见文本内容,后者显示所有内容(包括display属性为none的部分)

4.CSS Selector 语法选择元素

通过 CSS Selector 选择单个元素的方法是

find_element(By.CSS_SELECTOR, CSS Selector参数)

选择所有元素的方法是

find_elements(By.CSS_SELECTOR, CSS Selector参数)
  • 根据tag名选择元素:

    比如 要选择 所有的tag名为div的元素,就可以是这样

    py 复制代码
    elements = wd.find_elements(By.CSS_SELECTOR, 'div')

    等价于

    py 复制代码
    elements = wd.find_elements(By.TAG_NAME, 'div')
  • 根据id属性选择元素:

    语法是在id号前面加上一个井号: #id值

    py 复制代码
    element = wd.find_element(By.CSS_SELECTOR, '#id名')
  • 根据class属性选择元素:

    语法是在 class 值 前面加上一个点: .class值

    比如 这个网址 https://cdn2.byhy.net/files/selenium/sample1.html

    要选择所有 class 属性值为 animal的元素 动物 除了这样写

    py 复制代码
    elements = wd.find_elements(By.CLASS_NAME, 'animal')

    还可以这样写

    py 复制代码
    elements = wd.find_elements(By.CSS_SELECTOR, '.animal')

    因为是选择 所有 符合条件的 ,所以用 find_elements 而不是 find_element

验证CSS Selector

F12,点击 Elements 标签后, 同时按 Ctrl 键 和 F 键

5.选择 子元素 和 后代元素

  • 如果 元素2元素1 的 ++直接子元素++, CSS Selector 选择子元素的语法是这样的

    元素1 > 元素2

中间用一个大于号 (我们可以理解为箭头号)

注意,最终选择的元素是 元素2 , 并且要求这个 元素2元素1 的直接子元素

也支持更多层级的选择, 比如

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

就是选择 元素1 里面的子元素 元素2 里面的子元素 元素3 里面的子元素 元素4 , 最终选择的元素是 元素4

  • 如果 元素2元素1++后代元素++, CSS Selector 选择后代元素的语法是这样的

    元素1 元素2

中间是一个或者多个空格隔开

6.根据属性选择

css 选择器支持通过任何属性来选择元素,语法是用一个方括号 []

举例

py 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By

wd = webdriver.Chrome()

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

# 根据属性选择元素
element = wd.find_element(By.CSS_SELECTOR, '[href="http://www.miitbeian.gov.cn"]')

# 打印出元素对应的html
print(element.get_attribute('outerHTML'))

CSS 还可以选择 属性值 包含 某个字符串 的元素

比如, 要选择a节点,里面的href属性包含了 miitbeian 字符串,就可以这样写

a[href*="miitbeian"]

还可以 选择 属性值 以某个字符串 开头 的元素

比如, 要选择a节点,里面的href属性以 http 开头 ,就可以这样写

a[href^="http"]

还可以 选择 属性值 以某个字符串 结尾 的元素

比如, 要选择a节点,里面的href属性以 gov.cn 结尾 ,就可以这样写

a[href$="gov.cn"]

如果一个元素具有多个属性

html 复制代码
<div class="misc" ctype="gun">沙漠之鹰</div>

CSS 选择器 可以指定 选择的元素要 同时具有多个属性的限制,像这样 div[class=misc][ctype=gun]

7.选择语法联合使用

比如, 我们要选择 网页 html 中的元素 <span class='copyright'>版权</span>

html 复制代码
<div id='bottom'>
    <div class='footer1'>
        <span class='copyright'>版权</span>
        <span class='date'>发布日期:2018-03-03</span>
    </div>
    <div class='footer2'>
        <span>备案号
            <a href="http://www.miitbeian.gov.cn">苏ICP备88885574号</a>
        </span>
    </div>        
</div>         

CSS selector 表达式 可以这样写:

div.footer1 > span.copyright

就是 选择 一个class 属性值为 copyright 的 span 节点, 并且要求其 必须是 class 属性值为 footer1 的 div节点 的子节点

也可以更简单:

.footer1 > .copyright

就是 选择 一个class 属性值为copyright 的节点(不限类型), 并且要求其 必须是 class 属性值为 footer1 的节点的 子节点

当然 这样也是可以的:

.footer1  .copyright

因为子元素同时也是后代元素

8.组选择

如果我们要 同时选择所有class 为 plant class 为 animal 的元素。怎么办?

这种情况,css选择器可以 使用 逗号 ,称之为 组选择 ,像这样

html 复制代码
.plant , .animal

再看一个例子,比如选择所有 id 为 t1 里面的 span 和 p 元素

我们是不是应该这样写呢?

py 复制代码
#t1 > span,p

不行哦,这样写的意思是 选择所有 id 为 t1 里面的 span所有的 p 元素

只能这样写

py 复制代码
#t1 > span , #t1 > p

9.按次序选择子节点

(1)父元素的第n个子节点

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

使用 nth-child

如, 选择的是 第2个子元素,并且是span类型

所以这样可以这样写 span:nth-child(2)

如果你不加节点类型限制,直接这样写 :nth-child(2)

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

(2)父元素的倒数第n个子节点

选择的是父元素的 倒数第几个子节点 ,使用 nth-last-child

比如:

html 复制代码
p:nth-last-child(1)

就是选择第倒数第1个子元素,并且是p元素、

(3)父元素的第几个某类型的子节点

我们可以指定选择的元素 是父元素的第几个 某类型的 子节点

使用 nth-of-type

html 复制代码
 <div id='t1'>
           <h3> 唐诗 </h3>
           <span>李白</span>
           <p>静夜思</p>
           <span>杜甫</span>
           <p>春夜喜雨</p>              
  </div>    

比如,

我们要选择 唐诗 和宋词 的第一个 作者,

可以像上面那样思考:选择的是 第2个子元素,并且是span类型

所以这样可以这样写 span:nth-child(2)

还可以这样思考,选择的是 第1个span类型 的子元素

所以也可以这样写 span:nth-of-type(1)

(4)父元素的倒数第几个某类型的子节点

使用 nth-last-of-type

像这样

html 复制代码
p:nth-last-of-type(2)

(5)奇偶数节点

如果要选择的是父元素的 偶数节点,使用 nth-child(even)

比如

html 复制代码
p:nth-child(even)

如果要选择的是父元素的 奇数节点,使用 nth-child(odd)

html 复制代码
p:nth-child(odd)

如果要选择的是父元素的 某类型偶数节点,使用 nth-of-type(even)

如果要选择的是父元素的 某类型奇数节点,使用 nth-of-type(odd)

10.兄弟节点选择

(1)相邻兄弟节点选择

html 复制代码
       <h3> 唐诗 </h3>
       <span>李白</span>

选择 h3 后面紧跟着的兄弟节点 span。

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

表示元素 紧跟关系的 是 加号

(2)后续所有兄弟节点选择

如果要选择是 选择 h3 后面所有的兄弟节点 span,可以这样写 h3 ~ span

四.frame切换/窗口切换

暂略

五.文件上传

使用selenium自动化上传文件,我们只需要定位到该input元素,然后通过 send_keys 方法传入要上传的文件路径即可。

如下所示:

python 复制代码
# 先定位到上传文件的 input 元素
ele = wd.find_element(By.CSS_SELECTOR, 'input[type=file]')

# 再调用 WebElement 对象的 send_keys 方法
ele.send_keys(r'h:\g02.png')

但是,有的网页上传,是没有 file 类型 的 input 元素的。
【Selenimu+AutoIT】非input标签上传文件(带参数)

六.Xpath选择器

绝对路径选择

从根节点开始的,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式,就是某元素的 绝对路径

/html/body/div ,就是一个绝对路径的xpath表达式, 等价于 css表达式 html>body>div

相对路径选择

有的时候,我们需要选择网页中某个元素, 不管它在什么位置

xpath前面加 // , 表示从当前节点往下寻找所有的后代元素,不管它在什么位置。

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

py 复制代码
elements = driver.find_elements(By.XPATH, "//div//p")

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

py 复制代码
elements = driver.find_elements(By.CSS_SELECTOR,"div p")

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

如果使用CSS选择器,则为 div > p

通配符

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

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

py 复制代码
elements = driver.find_elements(By.XPATH, "//div/*")

根据属性选择

根据属性来选择元素 是通过 这种格式来的 [@属性名='属性值']

注意:

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

如:

python 复制代码
elements = driver.find_element(by=By.XPATH, value='//div[@role="textbox"]')

笔记来源

相关推荐
waterHBO2 小时前
python 爬虫 selenium 笔记
爬虫·python·selenium
chenjingming66610 小时前
windows使用tcpdump.exe工具进行抓包教程
网络·测试工具·tcpdump
小码哥说测试17 小时前
软件测试技术之 GPU 单元测试是什么!
自动化测试·功能测试·测试工具·jmeter·单元测试·集成测试·postman
全能全知者1 天前
不废话简单易懂的Selenium 页面操作与切换
python·selenium·测试工具·网络爬虫
测试19982 天前
使用Selenium进行网页自动化
自动化测试·软件测试·python·selenium·测试工具·自动化·测试用例
做一道光2 天前
1、QAC静态测试常用操作
软件测试·测试工具·静态测试
假女吖☌2 天前
postman接口关联
测试工具·postman
测试杂货铺2 天前
selenium元素定位:元素点击交互异常解决方法
自动化测试·软件测试·python·selenium·测试工具·职场和发展·单元测试
讓丄帝愛伱2 天前
PostMan使用变量
测试工具·postman
可愛小吉3 天前
Python 课程12-Python 自动化应用
开发语言·前端·selenium·openpyxl·reportlab