0


上手Selenium

目录

介绍

Selenium 是一套 Web网站的程序自动化操作解决方案。通过它,我们可以写出自动化程序,像人一样在浏览器里操作web界面。 比如点击界面按钮,在文本框中输入文字等操作。
支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera和Edge等。这里我将以Chrome为例进行Selenium功能的演示~

准备工作

安装selenium库

不同的编程语言选择不同的Selenium客户端库,对应我们Python语言来说,Selenium客户端库的安装非常简单,用 pip 命令即可。
打开命令行程序,运行如下命令:

pip install selenium

网络不好的话,可以使用豆瓣源:

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

安装浏览器驱动

浏览器驱动是和浏览器对应的。 不同的浏览器需要选择不同的浏览器驱动。
2.1 浏览器的选择
目前主流的浏览器中,谷歌 Chrome 浏览器对Selenium自动化的支持更加成熟一些。
2.2 检查浏览器版本
其实,有两种方式安装浏览器驱动:一种是常见的手动安装,另一种则是利用第三方库自动安装。
这里介绍手动安装,自动安装参见:https://mp.weixin.qq.com/s/_lsDLPpNI1zdSwaPgdTZHQ
首先需要查看浏览器版本(2种方式均可):
方式1:在浏览器的地址栏键入

Chrome://version

,即可查看浏览器版本号
image.png
方式2:点击“Chrome菜单”→“帮助”→“关于Google Chrome”,查看浏览器版本号
相当于地址栏输入:

chrome://settings/help

image.png
2.3 浏览器驱动的安装
下载地址:https://chromedriver.storage.googleapis.com/index.html
注意:驱动和浏览器的版本号越接近越好,但是略有差别,比如98和97 ,通常也没有什么问题。
image.png

初始化浏览器对象

通过调用浏览器驱动,可以打开浏览器,就可以了

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 创建 WebDriver 对象,指明使用chrome浏览器驱动# 注意,等号右边 返回的是 WebDriver 类型的对象,我们可以通过这个对象来操控浏览器,比如 打开网址、选择界面元素等。
wb = webdriver.Chrome(service=Service(r'C:\Users\asuka\Downloads\Compressed\chromedriver.exe'))# 添加 input,让程序保持运行状态input()

image.png
在创建WebDriver对象时,需要指定浏览器驱动路径,这样写有2个问题:

  1. 比较麻烦, 每次写自动化代码都 要指定路径。
  2. 如果你的代码给别人运行,他的电脑上存放浏览器驱动的路径不一定和你一样(比如他的电脑是苹果Mac电脑),得改脚本。

有什么好办法呢?我们可以把浏览器驱动 所在目录加入环境变量Path , 写代码时,就可以无需指定浏览器驱动路径了,像这样:

wd = webdriver.Chrome()

设置完环境变量后,别忘了重启IDE(比如 PyCharm) 新的环境变量才会生效。
image.png
其他报错、报毒问题,参见:原理与安装 | 白月黑羽

其他浏览器

其他浏览器,如:360、Edge,参见:https://mp.weixin.qq.com/s/0mCAEcdRdyVKzDrueMUlpw

操控浏览器的基本方法

访问页面

使用Get方法访问某网站

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 初始化浏览器为chrome浏览器
browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))# 访问百度首页
browser.get(r'https://www.baidu.com/')# 关闭浏览器
browser.close()

设置浏览器大小

get_window_size()

获取窗口大小

set_window_size()

方法可以用来设置浏览器大小(就是分辨率)

maximize_window

则是设置浏览器为全屏!

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
import time

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))# 获取当前窗口大小
browser.get(r'https://www.baidu.com')print(browser.get_window_size())# {'width': 838, 'height': 892}
time.sleep(2)# 设置浏览器大小:全屏
browser.maximize_window()
time.sleep(2)# 设置分辨率 500*500
browser.set_window_size(500,500)
time.sleep(2)# 设置分辨率 1000*800
browser.set_window_size(1000,800)
time.sleep(2)# 关闭浏览器
browser.close()

设置代理

网上搜的结果不能用,问ChatGPT问出了答案。
代理类型:HTTP代理
方式1:为浏览器驱动设置了环境变量
image.png

from selenium import webdriver

# 设置代理IP的地址和端口号,类型为 HTTP 代理
proxy_address ="127.0.0.1:8080"
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--proxy-server=http://"+ proxy_address)# 浏览器驱动访问网站
driver = webdriver.Chrome(options=chrome_options)
driver.get("https://www.baidu.com")# 关闭浏览器
driver.quit()

方式2:指明浏览器驱动位置
image.png

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

# 设置代理IP的地址和端口号,类型为 HTTP 代理
proxy_address ="127.0.0.1:8080"
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--proxy-server=http://"+ proxy_address)# 浏览器驱动访问网站
driver = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'), options=chrome_options)
driver.implicitly_wait(10)
driver.get('https://cn.bing.com/')# 关闭浏览器
driver.quit()

获取页面基础属性

一些基础属性如:网页标题、网址、浏览器名称、页面源码等信息。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
browser.implicitly_wait(5)
browser.get(r'https://www.baidu.com')# 获取当前窗口标题print(browser.title)# 获取当前窗口URL地址print(browser.current_url)# 浏览器名称print(browser.name)# 网页源码print(browser.page_source)# 关闭浏览器
browser.close()

无界面浏览器、截图

from selenium import webdriver

# 无界面的浏览器
option = webdriver.ChromeOptions()
option.add_argument("headless")
browser = webdriver.Chrome(options=option)# 访问百度首页
browser.get(r'https://www.baidu.com/')# 截图预览
browser.get_screenshot_as_file('截图.png')# 关闭浏览器
browser.close()

刷新页面

刷新页面是我们在浏览器操作时很常用的操作,这里

refresh()

方法可以用来进行浏览器页面刷新。

from selenium import webdriver
import time

browser = webdriver.Chrome()# 设置浏览器全屏
browser.maximize_window()
browser.get(r'https://www.baidu.com')
time.sleep(2)try:# 刷新页面
    browser.refresh()print('刷新页面')except Exception as e:print('刷新失败')# 关闭浏览器
browser.close()

前进后退

前进后退是我们在使用浏览器时非常常见的操作,这里

forward()

方法可以用来实现前进,

back()

可以用来实现后退。

from selenium import webdriver
import time

browser = webdriver.Chrome()# 设置浏览器全屏
browser.maximize_window()
browser.get(r'https://www.baidu.com')
time.sleep(2)# 打开必应页面
browser.get(r'https://cn.bing.com/')
time.sleep(2)# 后退到百度页面
browser.back()
time.sleep(2)# 前进的必应页面
browser.forward()
time.sleep(2)# 关闭浏览器
browser.close()

浏览器窗口切换

测试网站:https://cdn2.byhy.net/files/selenium/sample3.html
实现目标:访问必应网站,执行一次搜索,然后返回到测试网站
image.png
image.png
这里主要涉及到窗口切换,可以使用:

wd.switch_to.window(handle)

,这是一个列表对象,里面包括了当前浏览器里面所有的窗口句柄。所谓句柄,大家可以想象成对应网页窗口的一个ID。
此外,我们可以设置一个当前窗口让它记住,方便随时切回来。

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

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

得到如下代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/sample3.html')# 点击按钮,打开必应
link = wd.find_element(By.TAG_NAME,'a')
link.click()
time.sleep(3)# 记住当前窗口
mainWindow = wd.current_window_handle

# 找到必应窗口for hanle in wd.window_handles:
    wd.switch_to.window(hanle)# 切窗口if'Bing'in wd.title:# 发现某窗口的网页标题中有“Bing”break# 找到了print(wd.title)# 输出切到的新窗口的title# 开始搜索
wd.find_element(By.ID,'sb_form_q').send_keys('白月黑羽\n')
time.sleep(3)# 回退到之前记住的窗口
wd.switch_to.window(mainWindow)

time.sleep(3)
wd.close()

弹出对话框

有些网站点击的时候,会弹出的对话框。那么如果点出弹框,获取弹框内容,以及关闭弹框呢?
测试网站:https://cdn2.byhy.net/files/selenium/test4.html
Alert弹框
Alert 弹出框,目的就是显示通知信息,只需用户看完信息后,点击 OK(确定) 就可以了。
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/test4.html')# --- alert ---
wd.find_element(By.ID,'b1').click()# 打印 弹出框 提示信息print(wd.switch_to.alert.text)
time.sleep(3)# 点击 OK 按钮
wd.switch_to.alert.accept()

time.sleep(3)
wd.quit()

Confirm弹框
Confirm弹出框,主要是让用户确认是否要进行某个操作

# 如果我们想点击 OK 按钮,可以用 accept 方法
driver.switch_to.alert.accept()# 如果我们想点击 Cancel 按钮, 可以用 dismiss 方法
driver.switch_to.alert.dismiss()

image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/test4.html')# --- confirm ---
wd.find_element(By.ID,'b2').click()# 打印 弹出框 提示信息print(wd.switch_to.alert.text)# 点击 OK 按钮
wd.switch_to.alert.accept()# --- confirm ---
wd.find_element(By.ID,'b2').click()# 点击 取消 按钮
wd.switch_to.alert.dismiss()

time.sleep(3)
wd.quit()

Prompt弹框
出现 Prompt 弹出框 是需要用户输入一些信息,提交上去。
比如:当管理员在网站上选择给某个账号延期时,就可能会弹出 Prompt 弹出框, 要求输入延期多长时间。
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/test4.html')# --- prompt ---
wd.find_element(By.ID,'b3').click()# 获取 alert 对象
alert = wd.switch_to.alert

# 打印 弹出框 提示信息print(alert.text)# 输入信息,并且点击 OK 按钮 提交
alert.send_keys('web自动化 - selenium')
alert.accept()# 点击 Cancel 按钮 取消
wd.find_element(By.ID,'b3').click()
alert = wd.switch_to.alert
alert.dismiss()

time.sleep(3)
wd.quit()

冻结界面

当鼠标放到某个位置,会出现一些内容,如果想获取这些内容对应的位置,发现 F12不好用了,甚至有些时候通过“审查元素”都找不到(或者只能找到1个,不方便找其他的,如下图中的“影响推广”),这个时候就需要冻结界面了。
image.png
我们可以在控制台中输入

debugger

实现冻结效果。
image.png
那么,如果延迟数秒再冻结,就可以解决悬停显示问题了:

# 在 5000毫秒后,执行 debugger 命令
# debug状态有个特性,界面被冻住,不管我们怎么点击界面都不会触发事件。
setTimeout(function(){debugger}, 5000)

image.png

操控元素的基本方法

选择到元素之后,我们的代码会返回元素对应的 WebElement对象,通过这个对象,我们就可以操控元素了。
操控元素通常包括:

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

点击元素

点击元素非常简单,就是调用元素WebElement对象的

click

方法。前面我们已经学过。
这里我们要补充讲解一点。当我们调用 WebElement 对象的

click

方法去点击元素的时候, 浏览器接收到自动化命令,点击的是该元素的中心点位置。

element = wd.find_element(By.ID,'go')
element.click()

输入、点击、结果等待

演示如何输入一个内容,点击按钮,等待加载结果

假设要获取搜索结果中的第一个结果内容,这里要添加一个休眠时间,因为搜索出结果是需要时间的!
image.png
我想的是挺好的,但是代码一跑就出错了,抛了异常:NoSuchElementException,意思就是在当前的网页上 找不到该元素, 就是找不到 id 为 1 的元素。

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

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

element = wd.find_element(By.ID,'kw')
element.send_keys('通讯\n')

element = wd.find_element(By.ID,'1')print(element.text)

wd.quit()

image.png
出现这个问题的原因在于网站还没有来得及返回搜索结果,代码就索要结果了。因此代码需要等待网站搜索出结果才行,那要等多久呢?直接设置个sleep休眠显然不好,不如让代码反复try:

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

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

element = wd.find_element(By.ID,'kw')
element.send_keys('通讯\n')whileTrue:try:
        element = wd.find_element(By.ID,'1')print(element.text)breakexcept:# 添加一个休眠,防止网站响应慢导致程序进入死循环
        time.sleep(1)

wd.quit()# 结果
国美通讯
代码:600898

其实,Selenium提供了一个更合理的解决方案,是这样的:
当发现元素没有找到的时候, 并不立即返回找不到元素的错误。而是周期性(每隔半秒钟)重新寻找该元素,直到该元素找到,或者超出指定最大等待时长,这时才抛出异常(如果是 find_elements 之类的方法, 则是返回空列表)。
Selenium 的 Webdriver 对象有个方法叫

implicitly_wait

,可以称之为“隐式等待”,或者“全局等待”。该方法接受一个参数,用来指定最大等待时长。如果我们加入如下代码:

wd.implicitly_wait(10)

,那么后续所有的

find_element

或者

find_elements

之类的方法调用都会采用上面的策略。如果找不到元素, 每隔半秒钟再去界面上查看一次, 直到找到该元素, 或者过了10秒最大时长。

特别警告⚠:

implicitly_wait

是为了解决找不到的问题,但是找到的也有可能是错误的。
当你网购时选择收件地址,选择省、市、县……,你怎么切换都有结果,但是你需要等“市”加载完之后,才能选择“县”,这个时候

implicitly_wait

就不好使了,还是需要

sleep

一下。

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

wd = webdriver.Chrome()
wd.implicitly_wait(10)# 最久等待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)

wd.quit()# 结果
国美通讯
代码:600898

清空 & 输入

使用WebElement对象的

clear

方法清空输入框内容
使用WebElement对象的

send_keys

方法输入内容
测试靶场:https://cdn2.byhy.net/files/selenium/test3.html
image.png
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))# 设置浏览器全屏
browser.maximize_window()
browser.get(r'https://cdn2.byhy.net/files/selenium/test3.html')

element = browser.find_element(By.ID,'input1')
element.clear()# 清除输入框已有的字符串
element.send_keys('白月黑羽\n')# 输入新字符串input()

获取元素的文本内容

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

element = wd.find_element(By.ID,'1')print(element.text)

获取输入框里面的文字

对于input输入框的元素,要获取里面的输入文本,用text属性是不行的,这时可以使用element.get_attribute(‘value’)
测试靶场:https://www.byhy.net/_files/stock1.html
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))

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

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

element.send_keys('白月黑羽')print(element.get_attribute('value'))

browser.close()# 结果
白月黑羽

但是,有时候,元素的文本内容没有展示在界面上,或者没有完全完全展示在界面上。这时,用WebElement对象的text属性,获取文本内容,就会有问题。出现这种情况,可以尝试使用 element.get_attribute(‘innerText’) ,或者 element.get_attribute(‘textContent’)。
使用 innerText 和 textContent 的区别是,前者只显示元素可见文本内容,后者显示所有内容(包括display属性为none的部分)。具体可以参考这里

获取元素属性

通过WebElement对象的 get_attribute 方法来获取元素的属性值,比如要获取元素属性class的值,就可以使用 element.get_attribute(‘class’)
练习靶场:https://www.byhy.net/_files/stock1.html
练习目标:获取“包钢股份”的属性值
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))# 设置浏览器全屏
browser.maximize_window()
browser.get(r'https://www.byhy.net/_files/stock1.html')

element = browser.find_element(By.ID,'1')print(element.text +'\n')print(element.get_attribute('class'))input()# 结果
包钢股份
代码:600010

result-item

获取整个元素对应的HTML

要获取整个元素对应的HTML文本内容,可以使用

element.get_attribute('outerHTML')

如果,只是想获取某个元素内部的HTML文本内容,可以使用

element.get_attribute('innerHTML')

测试靶场:https://www.byhy.net/_files/stock1.html
image.png
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))

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

element = browser.find_element(By.ID,'1')# 获取整个元素对应的HTML文本内容print(element.get_attribute('outerHTML'))# 获取某个元素内部的HTML文本内容print(element.get_attribute('innerHTML'))

browser.close()

frame切入切出

获取frame元素或者iframe元素的内部数据时,需要先切入进去才能获取。

测试网站:https://cdn2.byhy.net/files/selenium/sample2.html
image.png
假设我们要获取所有的植物,但是会发现下面的代码运行结果为空。仔细观察源代码会发现,要找的植物位于iframe中。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')# 根据 class name 选择元素,返回的是 一个列表
elements = wd.find_elements(By.CLASS_NAME,'plant')for element in elements:print(element.text)

在html语法中,frame元素或者iframe元素的内部会包含一个被嵌入的另一份html文档。在我们使用selenium打开一个网页时,我们的操作范围缺省是当前的html,并不包含被嵌入的html文档里面的内容。如果我们要操作被嵌入的html文档中的元素,就必须切换操作范围到被嵌入的文档中。
使用 WebDriver 对象的 switch_to 属性进行切换,像这样:

wd.switch_to.frame(frame_reference)

其中, frame_reference 可以是 frame 元素的属性 name 或者 ID。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')# 切换到iframe中
wd.switch_to.frame('frame1')

elements = wd.find_elements(By.CLASS_NAME,'plant')for element in elements:print(element.text)# 结果
土豆
洋葱
白菜

还可以通过 frame 所对应的 WebElement 对象切换进去:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')# 切换到iframe中
element = wd.find_element(By.CSS_SELECTOR,'iframe[src="sample1.html"]')
wd.switch_to.frame(element)

elements = wd.find_elements(By.CLASS_NAME,'plant')for element in elements:print(element.text)# 结果
土豆
洋葱
白菜

最后,演示切入和切出,并获取点击“外部按钮”点出来的内容
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/sample2.html')# 切换到iframe中,获取植物# element = wd.find_element(By.CSS_SELECTOR, 'iframe[src="sample1.html"]')# wd.switch_to.frame(element)
wd.switch_to.frame('frame1')

elements = wd.find_elements(By.CLASS_NAME,'plant')for element in elements:print(element.text)# 切出,回到最外部的HTML中
wd.switch_to.default_content()# 点击外部的一个按钮
wd.find_element(By.ID,'outerbutton').click()# 获取点击出来的内容
elements = wd.find_elements(By.CSS_SELECTOR,'#add li')for element in elements:print(element.get_attribute('outerHTML'))

time.sleep(2)
wd.quit()# 结果
土豆
洋葱
白菜
<li>你点击了外部按钮</li>

高级方法1:模拟鼠标

这里需要导入ActionChains 类:

from selenium.webdriver.common.action_chains import ActionChains

鼠标移动

目标:让鼠标移动到百度首页的“更多”那里。
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://www.baidu.com/')from selenium.webdriver.common.action_chains import ActionChains
ac = ActionChains(wd)# 获取移动的位置 对应的元素
element = wd.find_element(By.CSS_SELECTOR,'[name="tj_briicon"]')# 移动到指定位置
ac.move_to_element(element).perform()

time.sleep(3)

wd.quit()

鼠标左右键

左键就是

click()

,很多地方都有演示。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)# 最久等待10秒
wd.get('https://www.byhy.net/_files/stock1.html')
time.sleep(2)# 输入
element = wd.find_element(By.ID,'kw')
element.send_keys('通讯')
time.sleep(2)# 点击
element = wd.find_element(By.ID,'go')
element.click()

time.sleep(2)
wd.quit()

鼠标右键:

  • ActionChains(wd):调用ActionChains()类,并将浏览器驱动browser作为参数传入
  • context_click(right_click):模拟鼠标双击,需要传入指定元素定位作为参数
  • perform():执行ActionChains()中储存的所有操作,可以看做是执行之前一系列的操作
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://www.baidu.com/')# 定位到要右击的元素,这里选的新闻链接
right_click = wd.find_element(By.LINK_TEXT,'新闻')# 执行鼠标右键操作
ActionChains(wd).context_click(right_click).perform()
time.sleep(2)# 关闭浏览器
wd.close()

鼠标拖拽

使用方法:

drag_and_drop(source,target)

演示靶场:https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
import time

browser = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
browser.implicitly_wait(10)
browser.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
time.sleep(2)# 切入 iframe
browser.switch_to.frame('iframeResult')# 开始位置
source = browser.find_element(By.CSS_SELECTOR,'#draggable')# 结束位置
target = browser.find_element(By.CSS_SELECTOR,"#droppable")# 执行元素的拖放操作
ActionChains(browser).drag_and_drop(source, target).perform()
time.sleep(5)# 关闭浏览器
browser.close()

元素的选择方法

在selenium自动化中,最最常用的操作就是点击和输入,要实现这个操作,经常会碰到的一个问题就是怎么找到点击和输入的位置?有以下几种方法帮助我们找到这些位置。

基本方法

记不全没关系,下面有好用的CSS表达式

根据 id属性 选择元素

我们可以把 id 想象成元素的编号, 是用来在html中标记该元素的。根据规范, 如果元素有id属性 ,这个id 必须是当前html中唯一的。所以如果元素有id, 根据id选择元素是最简单高效的方式。
练习靶场:https://www.byhy.net/_files/stock1.html
实现目标:查询股票代码

  1. 获取id属性

image.png

  1. 运行代码。这里一旦进入断点,页面中就会执行输入“通讯”,并且执行回车键,于是就查询出了结果。

image.png
如果我不使用回车键,而是想点击“查询”按钮呢?
image.png
image.png
代码如下:

  • 第11行代码:发起一个请求通过浏览器驱动转发给浏览器,告诉它,需要选择一个idkw的元素。浏览器 找到idkw的元素后,将结果通过 浏览器驱动 返回给 自动化程序, 所以 find_element 方法会返回一个 WebElement 类型的对象。这个WebElement 对象可以看成是对应 页面元素的遥控器。我们通过这个WebElement对象,就可以 操控对应的界面元素。
from selenium import webdriver
from selenium.webdriver.common.by import By

# 创建 WebDriver 对象
wd = webdriver.Chrome()# 调用WebDriver 对象的get方法 可以让浏览器打开指定网址
wd.get('https://www.byhy.net/_files/stock1.html')# 根据id选择元素,返回的就是该元素对应的WebElement对象
element = wd.find_element(By.ID,'kw')# 通过该 WebElement对象,就可以对页面元素进行操作了# 比如输入字符串到 这个 输入框里
element.send_keys('通讯')

element = wd.find_element(By.ID,'go')
element.click()# 正常结束程序
wd.quit()

根据 class属性 选择元素

web自动化的难点和重点之一,就是如何 选择 我们想要操作的web页面元素。
除了根据元素的id ,我们还可以根据元素的 class 属性选择元素。
练习靶场:https://cdn2.byhy.net/files/selenium/sample1.html
练习根据class属性选择元素
可以看到,所有的植物元素都有个class属性值为 plant,所有的动物元素都有个class属性值为 animal。
image.png
假设我要获取所有的动物:
于是得到脚本:

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对象
elements = wd.find_elements(By.CLASS_NAME,'animal')# 取出列表中的每个 WebElement对象,打印出其text属性的值# text属性就是该 WebElement对象对应的元素在网页中的文本内容for element in elements:print(element.text)# 结果
狮子
老虎
山羊

注意事项:
如果把

wd.find_elements(By.CLASS_NAME, 'animal')

改为

wd.find_element(By.CLASS_NAME, 'animal')

,那么返回的就是第一个class 属性为 animal 的元素, 也就是“狮子”
image.png

根据 tag名 选择元素

练习靶场:https://cdn2.byhy.net/files/selenium/sample1.html
我们可以通过指定参数为

By.TAG_NAME

,选择所有的tag名为 div 的元素,如下所示:

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)

image.png
升级一下,混合 id 属性和 tag 属性,来获取结果。
目标:获取红框中的数据
image.png

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

element = wd.find_element(By.ID,'container')# 限制 选择元素的范围是 id 为 container 元素的内部。
spans = element.find_elements(By.TAG_NAME,'span')for span in spans:print(span.text)# 结果
内层11
内层12
内层21

在后面学习了CSS表达式后,可以通过获取后代元素的方式简化代码:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

elements = wd.find_elements(By.CSS_SELECTOR,'#container  span')for element in elements:print(element.text)

根据 link定位、partial定位

这种方法顾名思义就是用来定位文本链接的:
image.png

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://www.baidu.com/')# 使用CSS表达式# wd.find_element(By.CSS_SELECTOR, '[href="http://news.baidu.com"]').click()# 使用基本方法
wd.find_element(By.LINK_TEXT,'新闻').click()

time.sleep(6)
wd.close()

有时候一个超链接的文本很长,我们如果全部输入,既麻烦,又显得代码很不美观,这时候我们就可以只截取一部分字符串,用这种方法模糊匹配了。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://www.baidu.com/')# 模糊匹配“新闻”中的部分字符
wd.find_element(By.PARTIAL_LINK_TEXT,'闻').click()

time.sleep(6)
wd.close()

CSS表达式

如果我们要选择的元素没有id、class属性,或者有些我们不想选择的元素也有相同的id、class属性值,怎么办呢?这时候我们通常可以通过CSS selector语法选择元素。这是一种很强大好用的选择方法。
练习靶场:https://cdn2.byhy.net/files/selenium/sample1.html

根据 tag名、id、class 选择元素

CSS Selector同样可以根据tag名、id属性和class属性来选择元素。
1.1 根据tag名选择元素的CSS Selector语法非常简单,直接写上tag名即可,比如要选择所有的tag名为div的元素,就可以是这样,下面第8行和第9行代码功能是一样的。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')# elements = wd.find_elements(By.TAG_NAME, 'div')
elements = wd.find_elements(By.CSS_SELECTOR,'div')for element in elements:print(element.text)

wd.close()

1.2 根据id属性选择元素的语法是在id号前面加上一个井号: #id值
尝试在下面的输入框中输入内容
image.png
image.png
下面第8行和第9行代码功能是一样的。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')# element = wd.find_element(By.ID, 'searchtext')
element = wd.find_element(By.CSS_SELECTOR,'#searchtext')

element.send_keys('你好啊')

wd.close()

1.3 根据class属性选择元素的语法是在 class 值 前面加上一个点: .class值
下面第8行和第9行代码功能是一样的。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')# elements = wd.find_elements(By.CLASS_NAME, 'animal')
elements = wd.find_elements(By.CSS_SELECTOR,'.animal')for element in elements:print(element.text)# 结果
狮子
老虎
山羊

根据属性选择

css选择器专门提供了常用属性 id、class 选择的语法,那么其他的属性呢?
css 选择器支持通过任何属性来选择元素,语法是用一个方括号 [] 。
举例:我想获取这个链接地址
image.png
测试代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

elements = wd.find_elements(By.CSS_SELECTOR,'[href="http://www.miitbeian.gov.cn"]')for element in elements:print(element.get_attribute('outerHTML'))
wd.quit()# 结果<a href="http://www.miitbeian.gov.cn">苏ICP备88885574号</a>

CSS还可以选择属性值包含某个字符串的元素比如,要选择a节点,里面的href属性包含了miitbeian字符串,就可以这样写:

a[href*="miitbeian"]
# 还可以选择属性值以某个字符串开头的元素。# 比如,要选择a节点,里面的href属性以http开头,就可以这样写
a[href^="http"]# 还可以选择属性值以某个字符串结尾的元素。比如,# 要选择a节点,里面的href属性以gov.cn结尾,就可以这样写
a[href$="gov.cn"]

子元素、后代元素、逻辑或

练习靶场:https://cdn2.byhy.net/files/selenium/sample1.html
网页代码如下所示:

  • id 为 container 的div元素直接包含了 id 为 layer1 和 layer2 的两个div元素
  • id 为 container 的div元素间接包含了id 为 inner11 、inner12 、inner22 的元素和三个span类型的元素
  • layer1 和 layer2是container的直接子元素
  • inner11 、inner12 、inner22、layer1、layer2是container的后代元素
<divid='container'><divid='layer1'><divid='inner11'><span>内层11</span></div><divid='inner12'><span>内层12</span></div></div><divid='layer2'><divid='inner21'><span>内层21</span></div></div></div>

上面的说法看懂看不懂无所谓,代码演示一下就懂了:
使用右箭头获取直接子元素

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

elements = wd.find_elements(By.CSS_SELECTOR,'#container  div')for element in elements:print(element.get_attribute('outerHTML'))print('-----------------')

wd.quit()

image.png
使用空格获取后代元素
image.png
现在尝试获取所有的植物:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1.html')

elements = wd.find_elements(By.CSS_SELECTOR,'.plant  span')for element in elements:print(element.get_attribute('outerHTML'))print(element.text)print('-----------------')

wd.quit()

image.png
验证CSS Selector
通过在浏览器中输入CSS Selector语法,可以很方便的判断语法是否正确,是否符合效果。
避免了在开发工具中反复调试代码。F12 ➡ Ctrl+F
image.png
进一步精准定位:

#bottom > .footer1 span.copyright

image.png
逻辑或:使用逗号进行分割,运行优先级低
案例1:获取所有的动物和植物
测试网站:https://cdn2.byhy.net/files/selenium/sample1.html
使用“逻辑或”直接获取:

.plant,.animal

image.png
案例2:获取唐诗中的所有作品和作者
测试网站:https://cdn2.byhy.net/files/selenium/sample1a.html
由于“逻辑或”的优先级低,因此使用:

#t1 span , #t1 p

image.png
父元素的第n个子节点
我们可以指定选择的元素是父元素的第几个子节点,使用

nth-child

案例1:
测试网站:https://cdn2.byhy.net/files/selenium/sample1b.html
使用:

span:nth-child(2)

,获取第2个子元素是span的数据
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/sample1b.html')

elements = wd.find_elements(By.CSS_SELECTOR,'span:nth-child(2)')for element in elements:print(element.get_attribute('outerHTML'))
wd.quit()# 结果<span>李白</span><span>苏轼</span>

案例2:由于没有指明第2个子节点的标签名,因此所有的第2个子节点都会被选上。

:nth-child(2)

image.png
这个东西可以正着数,也可以倒着数,如:父元素的倒数第n个子节点
使用:

nth-last-child

测试网站:https://cdn2.byhy.net/files/selenium/sample1b.html
目标:获取父元素倒数第1个子节点是p类型的:

p:nth-last-child(1)

image.png
父元素的第几个某类型的子节点
我们可以指定选择的元素是父元素的第几个某类型的子节点,使用

nth-of-type

举例如下,

p:nth-of-type(2)

匹配的子节点类型是

p

,这个

p

是第二个。
可以通俗的理解为,要从闺女(span)、侄子(span)、儿子(p)中寻找二儿子。
image.png
这个东西可以正着数,也可以倒着数,如:父元素的倒数第几个某类型的子节点

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

:获取子节点是

p

的,倒数第二个

p

image.png

奇数节点和偶数节点

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

兄弟节点选择

相邻兄弟节点选择,使用

+

进行选择

p + span

:p后面的同级别节点,第一个是span的就选上
image.png
后续所有兄弟节点选择,使用

~

进行选择

h3 ~ span

:h3后面的同级别节点,只要是span,就全选上
image.png
更多CSS选择器的介绍,可以参考 CSS 选择器参考手册

Xpath选择器

上面已经学习了CSS,为什么还要学习 Xpath呢? 因为:

  • 有些场景用 css 选择 web 元素 很麻烦,而xpath却比较方便。
  • 另外 Xpath 还有其他领域会使用到,比如爬虫框架 Scrapy, 手机App框架 Appium。

测试网站:https://cdn2.byhy.net/files/selenium/test1.html

绝对路径、相对路径

绝对路径:从根节点开始,到某个节点,每层都依次写下来,每层之间用 / 分隔的表达式。
可以通过浏览器直接复制出绝对路径,十分方便,假设我这里要获取所有的城市。
image.png
image.png
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(5)
wd.get(r'https://cdn2.byhy.net/files/selenium/test1.html')

elements = wd.find_elements(By.XPATH,'/html/body/div/div/div//p')for element in elements:print(element.text)

wd.close()# 结果
北京
上海
纽约
休斯顿
芝加哥

相对路径:

//

开始,选择内部直接子节点使用

/

,选择内部所有子节点使用

//

我还是习惯使用绝对路径,然后微调获取所有的外国城市:

//div/span/p

image.png

通配符

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

//div/*
*

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

div > *

代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(5)
wd.get(r'https://cdn2.byhy.net/files/selenium/test1.html')

elements = wd.find_elements(By.XPATH,'//div/*')for element in elements:print(element.get_attribute('outerHTML'))

wd.close()

根据属性选择

Xpath 可以根据属性来选择元素。
根据属性来选择元素是通过这种格式来的 [@属性名=‘属性值’]
注意:

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

方式1:根据id属性选择
选择 id 为 west 的元素,可以这样

//*[@id='west']/p

image.png
方式2:根据class属性选择
选择所有 select 元素中 class 为 single_choice 的元素,可以这样

//select[@class='single_choice']

方式3:其他属性
比如选择具有 multiple 属性的所有页面元素 ,可以这样

//*[@multiple]

(因为没有值,所以只写属性)
image.png
方式4:包含某字符
要选择 style 属性值包含 color 字符串的页面元素,可以这样

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

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

//*[starts-with(@style,'color')]

要选择 style 属性值以某个字符串结尾的页面元素,大家推测是

//*[ends-with(@style,'color')]

, 但是很遗憾,这是xpath 2.0 的语法 ,目前浏览器支持的是 xpath 1的语法。

选择第几个

  1. 要选择p类型第2个的子元素,就是://p[2]

注意,选择的是 p 类型第2个的子元素;并非选择第2个子元素类型是p。

  1. 选择父元素为div的第2个子元素,不管是什么类型://div/*[2]
  2. 选取p类型倒数第1个子元素://p[last()]
  3. 选取p类型倒数第2个子元素://p[last()-1]

范围选择

xpath还可以选择子元素的次序范围。

  1. 选取option类型第1到2个子元素://option[position()<=2]或者//option[position()<3]
  2. 选择class属性为multi_choice的前3个子元素://*[@class='multi_choice']/*[position()<=3]
  3. 选择class属性为multi_choice的后3个子元素:
//*[@class='multi_choice']/*[position()>=last()-2]

为什么不是 last()-3 呢? 因为:
last() 本身代表最后一个元素
last()-1 本身代表倒数第2个元素
last()-2 本身代表倒数第3个元素

逻辑或、父节点、兄弟节点✨

逻辑或
css有组选择(这里我称为“逻辑或”),可以同时使用多个表达式,多个表达式选择的结果都是要选择的元素。
比如,要选所有的option元素 和所有的 h4 元素,可以使用:

Xpath选择的语法
//option | //h4

等同于CSS选择器
option , h4

再比如,要选所有的 class属性为 single_choice 和 class属性为 multi_choice 的元素,可以使用:

Xpath选择的语法
//*[@class='single_choice'] | //*[@class='multi_choice']

等同于CSS选择器
.single_choice , .multi_choice

选择父节点⭐
Xpath可以选择父节点, 这是css做不到的。某个元素的父节点用

/..

表示。
如果某个元素没有特征,但是它的子节点有特征, 就可以采用这种方法。
比如,要选择 id 为 china 的节点的父节点,可以这样写

//*[@id='china']/..

后续兄弟节点
前面学过css选择器,要选择某个节点的后续兄弟节点,用波浪线。
Xpath也可以选择后续兄弟节点,用这样的语法

following-sibling::

比如,要选择 class 为 single_choice 的元素的所有后续兄弟节点

Xpath选择的语法
//*[@class='single_choice']/following-sibling::*

等同于CSS选择器
.single_choice ~ *

前面兄弟节点
xpath还可以选择前面的兄弟节点,用这样的语法

preceding-sibling::
要选择 class 为 single_choice 的元素的 所有 前面的兄弟节点,这样写
//*[@class='single_choice']/preceding-sibling::*

要选择 class 为 single_choice 的元素的前面最靠近的兄弟节点 , 这样写
//*[@class='single_choice']/preceding-sibling::*[1]

前面第2靠近的兄弟节点 , 这样写
//*[@class='single_choice']/preceding-sibling::*[2]

而 CSS选择器 目前还没有方法选择 前面的 兄弟节点!
更多Xpath语法,参见:XPath 教程

元素的选择场景:选择框

常见的选择框包括: radio框、checkbox框、select框
测试网址:https://cdn2.byhy.net/files/selenium/test2.html
请注意,演示的网站存在问题,点选其他框后,check不会发生变化,因此不再获取点选之后的结果了。
image.png

radio框

目标:先打印当前选中的老师名字,再选择小雷老师
网页代码:

<divid="s_radio"><inputtype="radio"name="teacher"value="小江老师">小江老师<br><inputtype="radio"name="teacher"value="小雷老师">小雷老师<br><inputtype="radio"name="teacher"value="小凯老师"checked="checked">小凯老师
</div>

开发代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/test2.html')# 获取当前选中的元素
element = wd.find_element(By.CSS_SELECTOR,'#s_radio input[checked="checked"]')print('当前选中的是:'+ element.get_attribute('value'))
time.sleep(3)# 点选 小雷 老师
wd.find_element(By.CSS_SELECTOR,'#s_radio input[value="小雷老师"]').click()
time.sleep(3)

wd.quit()

checkbox框

这种框可以多选。如果某个选项已经勾选了,再点击会取消选择。
image.png
目标:只勾选小雷老师
思路:先把已经选中的选项全部点击一下,然后再单独点击目标按钮

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/test2.html')# 获取当前选中的元素,由于可能有多个按钮被选中,因此使用 find_elements
elements = wd.find_elements(By.CSS_SELECTOR,'#s_checkbox input[checked="checked"]')for element in elements:print('当前选中的是:'+ element.get_attribute('value'))
    element.click()
time.sleep(3)# 点选 小雷 老师
wd.find_element(By.CSS_SELECTOR,'#s_checkbox input[value="小雷老师"]').click()
time.sleep(3)

wd.quit()

select框

radio框及checkbox框都是input元素,只是里面的type不同而已。select框则是一个新的select标签,Selenium专门提供了一个Select类进行操作。Select类提供了如下的方法:

# 根据选项的value属性值,选择元素
select_by_value

# 根据选项的次序(从1开始),选择元素
select_by_index

# 根据选项的可见文本,选择元素
select_by_visible_text
# 根据选项的value属性值,去除选中元素
deselect_by_value

# 根据选项的次序,去除选中元素
deselect_by_index

# 根据选项的可见文本,去除选中元素
deselect_by_visible_text

# 去除选中所有元素
deselect_all

Select单选框

Select单选框操作比较简单:不管原来选的是什么,直接用Select方法重新选择即可。
例如,选择示例里面的小雷老师,示例代码如下:
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import Select
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.implicitly_wait(10)
wd.get('https://cdn2.byhy.net/files/selenium/test2.html')

element = wd.find_element(By.ID,'ss_single')
select = Select(element)# 创建Select对象# 通过 Select 对象选中小雷老师
select.select_by_visible_text("小江老师")
time.sleep(3)

wd.quit()

Select多选框

用select类的

deselect_all

方法,全部取消勾选

select_by_visible_text

方法选择 小雷老师 和 小凯老师
image.png

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import Select
import time

wd = webdriver.Chrome(service=Service(r'D:\tools\selenium\chromedriver.exe'))
wd.get('https://cdn2.byhy.net/files/selenium/test2.html')# 创建Select对象
element = wd.find_element(By.CSS_SELECTOR,'#ss_multi')
select = Select(element)# 清除所有 已经选中 的选项
select.deselect_all()# 选择小雷老师 和 小凯老师
select.select_by_visible_text("小雷老师")
select.select_by_visible_text("小凯老师")

time.sleep(3)
wd.quit()

参考

2万字带你了解Selenium全攻略
2万字带你了解Selenium全攻略_selenium 2万字 教程_可以叫我才哥的博客-CSDN博客
原理与安装 | 白月黑羽

标签: selenium

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

“上手Selenium”的评论:

还没有评论