最近在学习爬虫的有关知识,发现一个很有意思的工具Selenium,所以打算花点时间看Selenium提供的手册来学习,为了防止以后忘记和方便复习,打算记录一下我的学习过程,我使用的Selenium版本是4.8.2。
目录
Selenium概述
网页操作
创建驱动会话
导航网页和关闭网页
刷新网页
退回上一页
前进下一页
查询与定位元素
获取元素信息
Actions接口交互
键盘操作
键盘按下和释放
键盘输入
键盘输入清除
键盘复制粘贴
鼠标操作
鼠标悬停
鼠标双击
单击并且长按住
单击并且瞬间释放
右键单击
长按拖动并释放
窗口操作
获取/设置窗口大小
获取/调整窗口位置
窗口大小格式设置
屏幕截图
关闭当前页面
获取窗口句柄
窗口 / 标签切换
Selenium概述
首先我们需要知道Selenium的功能和存在的价值:Selenium是一个自动化的测试工具,它用于帮助我们实现跨浏览器的自动化测试Web应用。我将理解为是通过提供一些工具帮助我们用编程语言自动化模仿浏览器的相关行为动作,其中我们常使用的API和协议是WebDriver。它定义了一个可以满足很多语言的接口,帮助我们实现浏览器应用程序的自动化测试,Selenium使用手册中对它的描述还提到:
WebDriver 不要求使用应用程序代码编译其 API, 因此它本质上不具有侵入性. 因此, 您测试的应用程序与实时推送的应用程序相同
在如何具体使用WebDriver之前手册还为我们提供了一些相关术语的介绍,这里我打算列一部分出来:
1、API:API是应用程序的编程接口,我们可以通过所提供的API来实现对WebDriver的控制和操作。
2、驱动程序(代理):这个很重要(相当于驱动遥控车的遥控器),我们使用WebDriver控制浏览器之前,我们首先要确保浏览器是可以和我们进行对话,也就是需要使用一套程序来作为中介连接浏览器和我们的控制代码,这套程序就是驱动程序。
网页操作
创建驱动会话
一个最简单的打开网页操作共分为三部:
- 获取驱动对话
- 导航到对应网页
- 关闭对话
首先我们从selenium模块里面导入webdriver。调用webdriver里面的Edge方法创建Edge浏览器的驱动对象(如果是Firefox则调用Firefox的方法、是谷歌则调用Chrome方法...)
from selenium import webdriver
driver = webdriver.Chrome()
# driver = webdriver.Edge()
# driver = webdriver.Firefox()
导航网页和关闭网页
然后我们像requests模块一样调用get方法来导航到网页:
driver.get("https://baike.baidu.com/item/百度百科")
最后打开网页后记得将我们的驱动对话给关闭:
driver.quit()
from selenium import webdriver
driver = webdriver.Edge()
driver.get("https://baike.baidu.com/item/百度百科")
driver.quit()
最后实现的效果如下,如果想让浏览器停一下目前可以先调用sleep函数来暂停一下。
刷新网页
刷新网页就是我们键盘中的F5的功能,我们调用驱动会话中的refresh方法进行刷新:
driver.refresh()
退回上一页
退回上一页就是回到上一个跳转的页面
我们常用下面的方法来实现:
driver.back()
前进下一页
前进上一页就是快进到下一个的页面
我们常用下面的方法来实现:
driver.forward()
查询与定位元素
常看到的网页由多个元素组合而成,我们利用selenium创建的操作会话可以用来定位到我们打开的网页里面的某个信息,一般来说是调用创建的驱动会话driver里的find_element方法来查找单个元素、find_elements来查找多个元素;find_element它会返回第一个符合要求的标签的位置信息,而find_elements会返回符合条件的所有标签位置信息元组,我们可以通过这些信息来找到里面的内容或者作为中介继续向下找内容:
driver.find_element(By.查找方式, "值")
driver.find_elements(By.查找方式, "值")
但是要记得在使用之前要从selenimu里面将By导入!!!
from selenium.webdriver.common.by import By
随后我们就可以根据不同的定位方式来定位到某一个标签,WebDriver在为我们提供了8种搜索方式可供我们选择,:
参数1 | 参数2 |
---|---|
CLASS_NAME | 定位class属性与搜索值匹配的元素(不允许使用复合类名) |
CSS_SELECTOR | 定位 CSS 选择器匹配的元素 |
ID | 定位 id 属性与搜索值匹配的元素 |
NAME | 定位 name 属性与搜索值匹配的元素 |
lLINK_TEXT | 定位link text可视文本与搜索值完全匹配的锚元素 |
PARTIAL_LINK_TEXT | 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素,则只选择第一个元素。 |
TAG_NAME | 定位标签名称与搜索值匹配的元素 |
XPATH | 定位与 XPath 表达式匹配的元素 |
以获取百度首页的热搜第三条为例,我们按下F12查看当前页面的元素element界面即可获取到这段我们想要获取的信息所处的标签的相关信息,利用这些标签信息就可以拿到我们所需的内容。
该文字段所处的标签的位置:
ID+TAG_NAME的方式:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
ret = driver.find_element(By.ID, "hotsearch-content-wrapper").find_elements(By.TAG_NAME,"span" )
print(ret[4].text)
driver.quit()
CSS的方式:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
print(driver.find_element(By.CSS_SELECTOR, "#hotsearch-content-wrapper > li:nth-child(2) > a > span.title-content-title").text)
driver.quit()
XPTH的方式:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
print(driver.find_element(By.XPATH, "//*[@id='hotsearch-content-wrapper']/li[2]/a/span[2]").text)
driver.quit()
获取元素信息
网页中的元素或者页面结构等会有很多信息,下面我们来看看如何获取一些元素的信息
查看元素是否显示的信息:
网页中有很多元素,但有时候如果出现某些问题,或许一些元素没有办法在上下文中显示出来,为了检查有没有正确显示某个函数,我们利用find_element下的.is_displayed方法确定,如果正确显示则返回True,反之为False
check = driver.find_element(By.查找方式, "值").is_displayed()
查看元素是否选定的信息:
selenium中提供了一个方法供我们判断当前页面的某个元素是否正在被选中,是则返回True,反之为False,这个功能常用于选择元素
check = driver.find_element(By.查找方式, "值").is_selected()
查看元素是否启用的信息:
页面中的某些元素可能由于某些情况会被禁用,所有我们需要有一个方法来判断当前元素是否目前是启用的,是则返回True,反之为False
check = driver.find_element(By.查找方式, "值").is_enabled()
查看元素的文本内容:
我们需要的网页内容很多情况下是存在于元素标签中的,要想获取元素标签中的信息,我们常用text属性
text = driver.find_element(BBy.查找方式, "值").text()
查看元素的标签名和CSS值:
我们利用下面的方法来获取元素的标签名
tag_name = driver.find_element(By.查找方式, "值").tag_name
查看元素的位置信息:
一个元素在我们的页面是有自己的特定x、y坐标以及它的长宽等信息,这些信息我们都可以通过下面的方法获取:
position = driver.find_element(By.查找方式, "值").rect
获取的某个元素位置信息:
查看元素的属性:
我们知道,元素标签里面会含有很多属性,这些属性不在标签里面夹着,这是在标签的尖角括号里面,我们要想拿到这些标签就需要使用get_attribute()这个方法,向其传入要查找的属性名即可返回对应属性名的属性值
href = driver.find_element(By.查找方式, "值").get_attribute('href')
target = driver.find_element(By.查找方式, "值").get_attribute('target')
这样我们就可以拿到a标签里面的href和target属性信息了:
网页:
输出:
Actions接口交互
首先我们要知道Actions是一个什么东西:Actions是一个低级的接口,能够向Web服务器提供虚拟化的输入。我们使用浏览器经常要用到鼠标、键盘等进行点击和键盘输入操作,下面我们来看看如何用Selenium给我们提供的Actions接口来模拟实现这些操作。
键盘操作
selenium中支持许多键盘按键,但是键盘主要的动作归根结底就是两个:按下和放开。这两个动作对应在selenium中就使用key_down和key_up两个方法来模拟。
键盘按下和释放
关于键盘按下和释放我们使用的是key_down和key_up方法,这两个方法位于类Actionchains中(Actionchains中记得传输驱动会话参数),同时按键存储在类Keys中,所以为了使用方便,在使用之前我们可以先将对应的方法直接导入:
from selenium.webdriver import ActionChains
from selenium.webdriver import Keys
当我们想在新打开的页面中按下shift和松开shift键就是使用下面的函数,它的参数就是我们要操作的按键,注意最后要调用perform()方法,否则操作会不显示出来。
ActionChains(driver).key_down(Keys.SHIFT).perform()
ActionChains(driver).key_up(Keys.SHIFT).perform()
因为驱动会话会记录我们输入过的操作指令,即使我们创建一个新的Actions类它也会记录我们之前的指针位置。所以如果我们想要进行连续的操作,需要在上次操作的基础上最后再加上ActionBuilder(driver).clear_actions()这个方法对驱动会话进行指令清理。
键盘输入
虽然我们有key_down和key_up两个方法表示按键的松紧,但是我们很多情况下发送信息都是由专门的方法进行发送到,这个方法就是send_keys,并且它不需要使用到Actionchains这个类
driver.find_element().send_keys(“文本内容”)
这个方法的主要思路是我们先找到页面中等待输入的元素,然后在找到的元素位置的基础上调用这个函数直接发送文本信息。
我们使用该方法打开百度然后搜索搜狗:
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from time import *
driver = webdriver.Edge()
driver.get("https://www.baidu.com")
sleep(2)
driver.find_element(By.XPATH, "//*[@id='kw']").send_keys("搜狗"+Keys.ENTER)
sleep(5)
driver.quit()
执行结果:
或者我们还可以使用Actionchains里的键入方法来进行输入,这就需要调用里面自带的send_keys_to_element方法了
ActionChains(driver).send_keys_to_element( 定位到的输入的位置,"输入内容").perform()
例如输入hello:
from selenium import webdriver
from time import *
from selenium.webdriver import ActionChains
from selenium.webdriver import Keys
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
ret = driver.find_element(By.XPATH, "//*[@id='kw']")
ActionChains(driver).send_keys_to_element( ret,"hello").perform()
ActionBuilder(driver).clear_actions()
driver.quit()
键盘输入清除
我们刚才在上面利用send_keys进行了输入,但是有时候我们往往需要对输入内容进行清空,这时候就需要使用我们的输入清空的方法了:
driver.find_element().clear()
例如我们将刚才输入的搜狗清除掉,改为输入360:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from time import *
driver = webdriver.Edge()
driver.get("https://www.baidu.com")
sleep(2)
ret = driver.find_element(By.XPATH, "//*[@id='kw']")
ret.send_keys("搜狗")
sleep(2)
ret.clear()
sleep(2)
ret.send_keys("360"+Keys.ENTER)
sleep(5)
driver.quit()
执行结果:
键盘复制粘贴
键盘的复制和粘贴也是我们常用到的操作,这里我使用send_keys来模拟实现全选、复制和粘贴:
from selenium import webdriver
from time import *
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
import sys
driver = webdriver.Edge()
driver.get("https://www.baidu.com/")
ret = driver.find_element(By.XPATH, '//*[@id="kw"]')
ret.send_keys("hello")
sleep(2)
ret.send_keys(Keys.CONTROL, 'a')
sleep(2)
ret.send_keys(Keys.CONTROL, 'x')
sleep(2)
ret.send_keys(Keys.CONTROL, 'v')
sleep(2)
driver.quit()
执行结果:
鼠标操作
我们使用鼠标常用到的操作一般是3个:点击,放开,移动。而针对这三个操作selenium中为我们提供了对应的操作方法。
鼠标悬停
鼠标悬停又被称为鼠标移动,就是将我们鼠标移动到某一个位置,它的具体实现函数是move_to_element(),需要向其传入鼠标的目标位置
ActionChains(driver).move_to_element(要悬停的目标元素的位置).perform()
鼠标双击
鼠标双击也是我们常用的功能,它主要依赖方法double_click,我们照旧传入目标元素位置即可
ActionChains(driver).double_click(要双击的目标元素).perform()
单击并且长按住
单击长按住的方法为调用Actionchains里面的click_and_hold方法,需要传入目标元素的位置即可
ActionChains(driver).click_and_hold(点击的元素位置).perform()
单击并且瞬间释放
一个完整的鼠标动作,一般都是单击某个元素为后会进行释放动作,所以我们需要看看如何进行释放动作,一般是调用Actionchains里面的click方法,它代表单击动作
ActionChains(driver).click(click_place).perform()
下面是一个完整的点击动作,点击百度页面的某个标签
from selenium import webdriver
from time import *
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
driver = webdriver.Edge()
driver.get('https://www.baidu.com/')
click_place = driver.find_element(By.XPATH, '//*[@id="hotsearch-content-wrapper"]/li[2]/a/span[2]')
ActionChains(driver).click(click_place).perform()
sleep(2)
driver.quit()
右键单击
对比左键,我们有时候也需要使用到右键单击,不同的是我们右键一般只有单击而不会去长按,而我们实现右键单击用的是context_click,并且传入要点击的位置即可
ActionChains(driver).context_click(要右键点击的目标元素位置).perform()
长按拖动并释放
想象一下,我们经常有将文件长按并且拖动到某个位置,而selenium也为我们提供了这个功能,通过调用drag_and_drop方法,向其传入初始元素(要拖动的元素)位置和要放置的目标元素的位置即可
ActionChains(driver).drag_and_drop(初始位置, 末尾位置).perform()
窗口操作
我们浏览器一般打开窗口不止会打开一个,所以我们很有必要去学校如何使用selenium里面的方法来操控这些窗口。在selenium中窗口和标签页没有进行仔细区分,不过我们都是可以通过句柄来进行控制这些窗口或者标签页。
获取/设置窗口大小
对于我们任意一个打开的窗口,它都会有一个窗口的宽和高,我们就可以通过调用driver驱动会话里面的方法get_window_size下面的get方法来获取宽和高,注意get里面的width和height不要拼错......
width = driver.get_window_size().get('width')
height = driver.get_window_size().get('height')
类似地,如果我们想要设置窗口的大小可以使用set_window_size方法:
driver.set_window_size(宽, 高)
获取/调整窗口位置
selenium中也为我们提供了一些获取窗口的位置和调整窗口位置的方法,它们的使用可以和前面获取/设置窗口大小的方法来类比:
获取窗口位置:
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')
调整窗口位置:
driver.set_window_position(x, y)
窗口大小格式设置
我们一般可以对窗口进行最大化、最小化、全屏等操作,selenium中也为我们提供了一些相关的操作以供我们更好操作窗口
窗口最大化:
driver.maximize_window()
窗口最小化:
driver.minimize_window()
窗口全屏:
driver.fullscreen_window()
屏幕截图
我们有时候或许需要对窗口的某些内容进行记录,这时候就需要我们进行屏幕截图了,在我的电脑我可以用shift+win+s来进行截图,但是selenium也为我们提供一个截图的方法,不过是整窗截图。
driver.save_screenshot('图片保存位置')
当然我们也可以进行元素局部截图,例如我想截图百度的logo,我可以将驱动会话改为当前元素位置,然后再调用screenshot方法也可以。
元素位置.screenshot('图片保存位置')
关闭当前页面
我们经常需要关闭一些页面,只保留一些有用的页面,在selenium中也为我们提供了一个类似于这样的方法:
driver.close()
但是这个方法和driver.quit()不同,这个方法代表的只是关闭当前的页面,而quit代表的则是关闭掉整个驱动会话。
获取窗口句柄
selenium中提供了一个获取窗口句柄的方法current_window_handle,它是一个driver的方法,我们通过调用它就可以获取当前窗口的句柄。
handle = driver.current_window_handle
窗口 / 标签切换
我们有时候会打开很多标签页,而我们浏览网页的时候有时候会返回去看之前的标签页,这个过程就是一个切换标签的过程,这个切换标签的操作selenium中也为我们提供了。
我们网页上的标签都会被存到一个名为window.handles的属性里面,而切换标签的动作是调用驱动会话driver里面的swith_to下面的window方法,向其传入要前往的标签句柄即可。
driver.switch_to.window(目标标签的ID)
下面是一个切换标签的例子:
from selenium import webdriver
from time import *
from selenium.webdriver.common.by import By
driver = webdriver.Edge()
driver.get("https://www.baidu.com")
original_ID = driver.current_window_handle
driver.find_element(By.XPATH, '/html/body/div[1]/div[1]/div[5]/div/div/div[3]/ul/li[1]/a').click()
sleep(2)
driver.switch_to.window(original_ID)
sleep(2)
driver.switch_to.window(driver.window_handles[1])
sleep(2)
driver.quit()
实际效果:
无头浏览器
所谓的无头浏览器是指我们使用selenium进行自动化操作浏览器的时候浏览器不出现,只在后台进行操作。要想实现无头浏览器需要加上下面的代码:
参考资料:
Selenium操作手册
selenium用法详解【从入门到实战】【Python爬虫】【4万字】_Dream丶Killer的博客-CSDN博客
自动化测试——selenium(完结篇)_selenium自动化测试_鸢也的博客-CSDN博客