2021-04-08 Selenium元素定位实战

  1. 认识Selenium

Selenium 是一个用于Web 应用程序的自动化测试工具。Selenium 直接运行在浏览器中,它可以模拟用户的行为操作,操作界面友好。Selenium 支持 IE、Google Chrome、Firefox、Opera等主流浏览器,同时Selenium也支持主流开发语言,如 Java、Python、C#等

  1. Selenium结合浏览器实战

针对不同的浏览器,需要下载不同的驱动程序(Driver)。以Firefox 浏览器为例(需要先下载最新火狐浏览器),在https://github.com/mozilla/geckodriver/releases/网站中选择“geckodriver-v0.29.0-win64.zip(目前为止最新)”下载并解压文件后,把Geckodriver.exe文件放在Python安装程序的目录下,也就是E:\Python3(根据自己配置的python环境放在python.exe的当前路径下,当然也可以自己建一个文件夹,不过要添加环境变量,python.exe已经默认了环境变量)。针对Firefox浏览器的测试代码如下:运行后如果不报错,那么就成功了

from selenium import webdriver
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.get(url=url)
driver.quit()
  1. 元素定位实战

在UI自动化测试中,最基础最核心的技能是对页面元素进行定位,定位到相应的元素后才可以对页面的操作进行编码验证。

  1. 单个元素定位实战

在Selenium自动化测试中,提供了单个元素定位方式和多个元素定位方式。两种方式都是根据元素属性 ID、NAME、CLASS_NAME、TAG_NAME、CSS_SELECTOR、XPATH、LINK_TEXT、PARTIAL_LINK_TEXT 来进行定位。下面就通过具体的实例说明单个元素定位在UI自动化测试中的应用。

3.1 find_element_by_id
如图,谷歌浏览器按F12开发者模式选中输入框


image.png
from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_id('kw').send_keys('selenium') #自动在百度输入框中输入'selenium',用by_id方式定位
time.sleep(5)
driver.quit()

以上可以精准找到百度input输入框,可以自行运行试看

3.2 find_element_by_name

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_name('wd').send_keys('selenium') #自动在百度输入框中输入'selenium',用by_name方式定位
time.sleep(5)
driver.quit()

以上也可以精准找到百度input输入框,可以自行运行试看

3.3 .find_element_by_class_name

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_class_name('s_ipt').send_keys('selenium') #自动在百度输入框中输入'selenium',用by_class_name方式定位
time.sleep(5)
driver.quit()

以上也可以精准找到百度input输入框,可以自行运行试看

3.4 find_element_by_xpath
获取的方式是定位到百度搜索输入框的元素属性后,用鼠标右键点击该属性,在弹出的快捷菜单中上选择“Copy”选项,在“Copy”子选项中选择“Copy Xpath”选项,如图所示。


image.png
from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_xpath("//*[@id='kw']").send_keys('selenium')#自动在百度输入框中输入'selenium',用xpath方式定位
time.sleep(5)
driver.quit()

以上也可以精准找到百度input输入框,可以自行运行试看

3.5 find_element_by_link_text

LINK_TEXT用于对超链接的处理。在HTML的代码中主要是以标签a对应,方法是find_element_by_link_text。以点击百度首页的“新闻”链接为例,查看“新闻”对应的代码:<a href="http://news.baidu.com" name="tj_trnews"class="mnav">新闻</a>。依据代码可以看到它是以 a 标签的。下面实现点击百度首页的“新闻”链接,实现的代码如下:

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_link_text(u"新闻").click()#自动点击百度新闻超链接
time.sleep(5)
driver.quit()

3.6 find_element_by_partial_link_text

PARTIAL_LINK_TEXT 也用于对超链接的处理,它与 LINK_TEXT 不同的是,它是按模糊搜索方式处理的。例如,在百度首页包含“闻”字的只有新闻链接,那么操作的时候只需要填写“闻”字就可以定位成功,方法是find_element_by_partial_link_text。仍以实现点击百度首页的“新闻”链接为例,代码如下:

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_partial_link_text(u'闻').click() #自动模糊匹配点击百度新闻超链接
time.sleep(5)
driver.quit()

3.7 find_element_by_css_selector
当使用ID、NAME等方式定位不到元素的时候,可使用CSS_SELECTOR,方法是find_element_by_css_selector
使用方式如find_element_by_xpath

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
driver.find_element_by_css_selector('#kw').send_keys('selenium')#自动在百度输入框中输入'selenium',用by_css方式定位
time.sleep(5)
driver.quit()
  1. 多个元素定位实战

在工作中,某些时候可能会发现元素的ID、NAME、CLASS_NAME等元素属性是一致的,这时,使用ID、NAME、CLASS_NAME等这些元素属性定位时就无法准确地定位到具体的元素。例如,在百度首页中,以TAG_NAME元素属性来定位百度搜索输入框,在代码中发现不仅仅在百度搜索输入框有 input 标签,在百度搜索输入框之前也有 input 标签,这时该如何定位呢?这时可以使用多个元素定位的方式。当定位到多个元素后,结果将以列表形式呈现,然后可以按照列表的索引来定位到具体的元素位置。下面以ID、TAG_NAME为例进行讲解。

3.2.1 find_elements_by_tag_name
以百度搜索输入框为例,使用 TAG_NAME的方式来实现定位,它的TAG_NAME是input,首先来获取百度首页的input标签,并且查看它的类型,代码如下:

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
tag_names=driver.find_elements_by_tag_name('input')#查找多个tag_name是input的标签
for tag_name in tag_names:
    print(tag_name)
print(type(tag_names))
time.sleep(5)
driver.quit()

显示:

<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="c9a5079b-dcb2-4c95-8ea8-c89481dd28da")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="ac186d77-1230-4dbb-b315-68d8a19433bc")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="80bcf2b9-4c85-4890-9858-711e445ac52b")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="31fab697-2d82-42e1-ab82-69d11d98a2c8")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="b5b40ed1-ccd1-4ab7-b6f1-79b3b6e8bb20")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="08a8419c-5c63-4eb2-ac51-11c0e8c20aae")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="6df6e33a-652f-487a-a1f1-3ab2a4875000")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="50cfc5e3-de93-4b85-94f0-0267f8c55367")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="166d64e7-8086-445e-94ce-e7f912c8f783")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="5ae33151-3175-40a7-98ea-baa3d3c5253b")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="6f536224-37b7-4b35-95d7-793e4070bf26")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="0658bacb-625f-4e84-8716-7bbd8d0b4576")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="d0cf47e4-11a2-4d51-9235-f6c588675f08")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="e1b5a5f3-e156-4264-a7e4-e93ca0465a7f")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="6e3d24ba-903f-4b1e-a771-93d9074c9544")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="35961a93-6b88-4b2d-bf55-a4a3ff2aa58c")>
<selenium.webdriver.firefox.webelement.FirefoxWebElement (session="e0709efe-1afb-4ef5-9b2e-e77dc3d12c7a", element="6d58e3dd-b089-46a6-8681-19b7ca114a91")>
<class 'list'>
Process finished with exit code 0

注解:从以上代码和输出结果中,可以看到,input的数据类型是 list,那么百度首页搜索输入框是在input标签中的第8位,也就是对应的索引是7(索引是从0开始),如图所示。


image.png

实际代码如下:

from selenium import webdriver
import time
url="https://www.baidu.com/"
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get(url=url)
tag_names=driver.find_elements_by_tag_name('input')[7].send_keys('selenium')#查找多个tag_name是input的标签,第7个就是要的
time.sleep(5)
driver.quit()

3.2.2 find_elements_by_id

先自定义一个html文件文件名index.html,内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="success.html" method="post">
    <center>
        <p>用户名: <input type="text" id="login" name="username"></p>
        <p>密码:<input type="text" id="login" name="password"></p>
        <p><input type="submit" id="login" value="登录"></p>
    </center>
</form>
</body>
</html>

在以上代码中可以看到用户名输入框、密码输入框,以及“登录”按钮的ID 一致,现在希望通过脚本输入用户名和密码,点击“登录”按钮,跳转到success.html的页面,并且使用 ID来定位。在以上代码中看到用户名和密码输入框,以及登录按钮的ID一致,实现的代码如下:

from selenium import webdriver
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
#根据自己实际路径填写
driver.get('file:///E:/test01/index.html')
ids=driver.find_elements_by_id('login')
#输入用户名
ids[0].send_keys('hcc')
#输入密码
ids[1].send_keys('123')
#点击登录
ids[2].click()
driver.quit()

PS:不要去纠结代码报错,这里只看方式

  1. By类的分析

导入模块:from selenium.webdriver.common.by import By

如果在定位元素属性中包含了如 ID 等元素属性,那么在一个测试中,元素定位具体有哪几种方式,可以在by模块中的By类中看到。By类的代码如下:

"""
The By implementation.
"""


class By(object):
    """
    Set of supported locator strategies.
    """

    ID = "id"
    XPATH = "xpath"
    LINK_TEXT = "link text"
    PARTIAL_LINK_TEXT = "partial link text"
    NAME = "name"
    TAG_NAME = "tag name"
    CLASS_NAME = "class name"
    CSS_SELECTOR = "css selector"

注解:在By 类中,类属性实际就是元素定位的方式,经常使用的有 ID、NAME等。

  1. iframe元素定位实战

在自动化测试中,如果无法定位到一个元素,那么最大的可能是定位的元素属性在iframe 框架中。iframe 对象代表一个HTML 的内联框架,在HTML 中iframe每出现一次,一个iframe对象就会被创建。

4.1 .处理未嵌套的iframe
图4.1


image.png

实现以上截图效果的HTML代码如下。其中frame.html代码为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<center>
    <a href="frame-1.html" target="10">练习课堂</a>
    <a href="frame-2.html" target="10">Python接口测试实战</a><br><br>
</center>
<iframe id="text" src="frame-1.html"  name="10-20" width="500" height="170" align="center" >

</iframe>
</body>
</html>

frame-1.html代码为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<center>
    <font size="5">练习课堂</font>
</center>
    Python自动化教程,欢迎大家关注<br>
</body>
</html>

frame-2.html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<center>
    <font size="5">Python接口测试实战</font> <br> <br>
</center>
基于python语言的接口自动化测试实战课程
</body>
</html>

在图4.1中,想要获取iframe框架中的“练习课堂”,实现的代码如下:

from selenium import webdriver
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get('file:///C:/Users/Administrator/Desktop/testpy/frame.html')#根据自己实际路径
driver.switch_to.frame('text')#通过id切换到frame中
#driver.switch_to.frame(0) #通过索引进入到frame框架
text1=driver.find_element_by_xpath('/html/body/center/font').text
print(text1)
driver.quit()

4.2 处理嵌套的iframe

下面来看嵌套的iframe 在自动化测试中如何进行元素定位,以及如何跳出嵌套。嵌套页面的效果如图4.2所示。

图4.2


image.png

在图4.2中可以看到在一个页面里面嵌套了Bing 搜索的首页,该页面的HTML代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html" charset="UTF-8">
    <title>嵌套的页面</title>
</head>
<body>
<center>
    <iframe id="son" src="http://www.bing.com" width="800" height="400" frameborder="0">

    </iframe>
</center>
<br> <br>
</body>
</html>

在该页面要实现 Bing的搜索效果,首先需要进入到 iframe框架中,然后再定位Bing首页搜索输入框的元素属性。该iframe的ID是son,Bing首页搜索输入框的元素属性 ID是 sb_form_q。实现在Bing首页搜索输入框中输入搜索关键字的代码如下:

from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get('file:///C:/Users/Administrator/Desktop/testpy/bing.html')#根据自己实际路径
driver.switch_to.frame('son')
driver.find_element_by_id('sb_form_q').send_keys('selenium')
time.sleep(5)
driver.quit()

下面是一个多层级的嵌套页面在自动化测试中的应用实例,如图4.3所示。
图4.3


image.png

HTML代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html" charset="UTF-8">
    <title>多层嵌套</title>
</head>
<body>
<center>
    <iframe id="parent" src="bing.html" width="1000" height="300" align="center"  frameborder="0">
    </iframe>
</center>
<hr>
<center>
    请输入用户名: <input type="text" id="userid" name="username" class="classname">
</center>
</body>
</html>

在以上 HTML代码中,可以看到 Bing首页的搜索多了二层嵌套,页面层级结构如图4-3-1所示。
图4-3-1


image.png

要想在Bing 首页搜索输入框中输入搜索关键字 Selenium,然后在下面的用户名输入框中输入Selenium,实现的代码如下:

from selenium import webdriver
import time
driver=webdriver.Firefox()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get('file:///C:/Users/Administrator/Desktop/testpy/second.html')#根据自己实际路径
#根据id进入到第一层frame框架中
driver.switch_to.frame('parent')
#根据id进入到第二层frame框架中
driver.switch_to.frame('son')
#输入搜素关键字selenium
driver.find_element_by_id('sb_form_q').send_keys('selenium')
time.sleep(5)
#5秒后清空输入的关键字
driver.find_element_by_id('sb_form_q').clear()
#跳出frame框架
driver.switch_to.default_content()
#用户名输入框中输入selenium
driver.find_element_by_name('username').send_keys('selenium')
time.sleep(5)
#5秒后清空输入用户名的关键字
driver.find_element_by_name('username').clear()
driver.quit()

结尾总结:


Selenium元素定位实战.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容