python+selenium 系列 ---04 元素定位

本贴最后更新于 1833 天前,其中的信息可能已经时移世改

前言

本篇主要讲述 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中,那就切换

后记

基础的东西已经差不多了,下篇就准备说下怎么构建一个比较完整的工程了。

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    536 引用 • 672 回帖
  • 自动化测试
    10 引用 • 27 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • someone

    感觉看作者这篇文章还是需要一定基础的,感谢作者的分享