前言
本篇主要讲述 selenium 的元素定位方式,定位方式基本都会提到,这篇文章过后,会对 selenium 的定位方式有一定了解,其实个人感觉元素定位并不是难点,不管用那种方式,肯定是能定位到的,但是哪种方式便于维护等等一系列问题,这都是需要思考的,后面的文章里会逐渐提及。
定位方式汇总
定位方法 | 定位单个元素 | 定位多个元素 |
---|---|---|
使用 ID | find_element_by_id("id 值") | |
find_element(by="id", value="id 值") |
按理说 id 值是唯一的,不能定位多个,但是 selenium 提供了 find_elements_by_id 的方法,如果 id 不唯一也能用,但是一般上 id 是唯一的 | |
使用 name | find_element_by_name("name 值") find_element(by="name", value="name 值") |
find_elements_by_name("name 值") find_elements(by="name", value="name 值") |
使用 class name | find_element_by_class_name("class name 的值") find_element(by="class name", value="class name 的值") |
find_elements_by_class_name("class name 的值") find_elements(by="class name", value="class name 的值") |
使用 tag | find_element_by_tag_name("tag name 值") find_element(by="tag name", value="tag name 值") |
find_elements_by_tag_name(tag name 值) find_elements(by="tag name", value="tag name 值") |
使用 link | find_element_by_link_text("a 标签的文本值") find_element(by="link text", value="a 标签的文本值") |
find_elements_by_link_text("a 标签的文本值") find_elements(by="link text", value="a 标签的文本值") |
使用 xpath | find_element_by_xpath('xpath 值') find_element(by="xpath",value='xpath 值') |
find_elements_by_xpath('xpath 值') find_elements(by="xpath",value='xpath 值') |
使用 css | find_element_by_css_selector("css selector 值") find_element(by="css selector",value='selector 值') |
find_elements_by_css_selector("css selector 值") find_elements(by="css selector",value='selector 值') |
上面列举了常用的几种定位方式,
其中:
find_element_by_id() 常用
find_element_by_name() 常用
find_element_by_class_name() 不甚靠谱,而且如果 classname 中间的 class 值有多个,也就是空格分开的那种,自己体会一下吧
find_element_by_link_text() 定位一些文字链接挺好用的
find_element_by_xpath() 灵活,基本没有定位不到的,这个需要对 xpath 有一定了解,其实现在浏览器打开 f12,找到对应元素,基本都有拷贝 xpath 的功能,当然,自己写也可以
find_element_by_css_selector() 灵活,基本没有定位不到的,这种需要对 css 选择器有一定了解,其实看看基本就清楚了,不清楚的,找下 css 选择器的相关东西
下面会以百度首页为例来展示对应代码
# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
driver = webdriver.Chrome(executable_path="xxxxx/chromedriver.exe")
driver.get("http://www.baidu.com")
# 通过id方式定位到百度首页输入框
# driver.find_element_by_id("kw").send_keys("第一个脚本") #第一种方式
# driver.find_element(by="id", value="kw").send_keys("第一个脚本") # 第二种方式
# driver.find_element(by=By.ID, value="kw").send_keys("第一个脚本") # 跟上面的一样,需要导入from selenium.webdriver.common.by import By,这个类里定义了这些常量
# 通过name方式定位百度首页输入框
# driver.find_element_by_name("wd").send_keys("第一个脚本")
# driver.find_element(by="name", value="wd").send_keys("第一个脚本")
# 通过name方式定位百度首页输入框
# driver.find_element_by_class_name("s_ipt").send_keys("第一个脚本")
# driver.find_element(by="class name", value="s_ipt").send_keys("第一个脚本")
# 通过tag方式定位百度首页输入框
# 这个是根据tag来,比如想找<input>,那tagname就是input,这种定位方式一般定位出来很可能是多个,所以如果想获取特定的,需要结合其他的属性
# inputs = driver.find_elements_by_tag_name("input")
# inputs = driver.find_elements(by="tag name", value="input")
# for input in inputs:
# if input.get_attribute("name") == "wd": # 如果name属性等于wd
# input.send_keys("第一个脚本")
# 通过link方式获取百度首页"新闻"的链接地址
# news_link = driver.find_element_by_link_text("新闻").get_attribute("href")
# news_link = driver.find_element(by="link text", value="新闻").get_attribute("href")
# print(news_link)
# 通过xpath方式定位百度首页输入框
# driver.find_element_by_xpath('//*[@id="kw"]').send_keys("第一个脚本")
# driver.find_element(by="xpath",value='//*[@id="kw"]').send_keys("第一个脚本")
# 通过css方式定位百度首页输入框
# driver.find_element_by_css_selector("#kw").send_keys("第一个脚本")
driver.find_element(by="css selector",value='#kw').send_keys("第一个脚本")
driver.find_element_by_id("su").click()
sleep(3)
driver.quit()
一些常见的元素定位不到的原因
实际中,在调试代码的时候,经常会有“selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element”,其实这种错误也算是比较好解决的了,无非就是元素定位不到,那就找原因就行了。
- frame 原因
- 新开窗口(标签页)原因
对于新手来说,最常见的基本就这两类原因了
frame 原因
有的页面是它还嵌套了另外一个页面,这个时候,写页面的时候就会用到 frame,iframe 这东西了,对于我们测试定位来说会牵扯到一个问题,简单理解就是,selenium 只能解析当前页面的东西,如果嵌入了另外一个页面,他就找不到了,由于没有找到 iframe 的页面,就暂时说下解决办法,就一行代码
driver.switch_to.frame(driver.find_element_by_xxx(""))# 我常用的是用WebElement对象来定位
# 如果想切到原来的frame,就用下面的代码
driver.switch_to.default_content()
# 如果有嵌套frame,那就按照这种方法,一层一层往里切
新开窗口(标签页)原因
定位不到的原因其实简单来说跟上面的差不多,就是新开的窗口,他就又定位不到了,要想定位到,那就切换到新开的那个窗口就行了
driver.switch_to.window("窗口句柄")#里面填的是窗口句柄,这个东西怎么获取了?
# 获取思路:(不建议根据列表下表获取)
# 假如新开了一个标签页,也就是当前有两个窗口了
# 1.获取当前所有window_handles,顺带获取第一个,也就是当前窗口的句柄
# 2.循环所有句柄,顺带判断,如果句柄不等于第一个窗口的句柄,就说明句柄是第二个窗口的了,那就切换
all_handles = driver.window_handles
current_handle = driver.current_window_handle
for handle in all_handles:
if handle != current_handle:
driver.switch_to.window(handle)
# 如果有更多的handles了?看你自己怎么实现了,可以把以前的handle存成list,然后遍历所有窗口,如果handle不在所有以前的handle的那个list中,那就切换
后记
基础的东西已经差不多了,下篇就准备说下怎么构建一个比较完整的工程了。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于