Web自动化之Selenium 超详细教程(python)

Selenium是一个开源的基于WebDriver实现的自动化测试工具。WebDriver提供了一套完整的API来控制浏览器,模拟用户的各种操作,如点击、输入文本、获取页面元素等。通过Selenium,我们可以编写自动化脚本,实现网页的自动化测试、数据采集等功能。它支持多种浏览器,如Chrome、Firefox、Edge等,并且提还供了丰富的语言绑定,包括Python、Java、C#等,使得开发者可以根据自己的需求选择合适的语言和工具链进行开发。

本文所有内容基于作者本人在使用python selenium进行web自动化任务时所遇到的实际问题和解决方案进行整理和总结。希望这些经验能够帮助到正在学习或使用python selenium进行web自动化的朋友们。

selenium下载

python 复制代码
pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple selenium

WebDriver下载

在使用python Selenium进行web自动化测试或数据采集之前,我们需要下载与浏览器相对应的WebDriver。WebDriver是Selenium与浏览器进行交互的桥梁,不同的浏览器需要下载对应的WebDriver。对于Chrome浏览器,我们需要下载ChromeDriver;对于Firefox浏览器,我们需要下载GeckoDriver。这些WebDriver可以从各自浏览器的官方网站或Selenium的官方GitHub仓库中下载。

下载完成后,我们需要将WebDriver的路径添加到系统的环境变量中,或者在代码中指定WebDriver的路径,以便Selenium能够正确地找到并使用它。正确下载和配置WebDriver是使用Selenium进行web自动化的第一步。

这里以edgedriver为例,其他浏览器的webdriver配置大同小异。

前往Edge的webdriver官网,https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?form=MA13LHhttps://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/?form=MA13LH

根据自己的电脑配置选择一个版本下载即可(不需要选择特别新的版本,稳定版本的就可以)

下载时有的用户不知道自己的windows电脑的cpui架构是x86还是x64的,这里,我们只需要在cmd中输入systeminfo命令后在弹出的提示符中的系统类型中便可以看到自己电脑的cpu架构。

下载完成之后将edgedriver.exe文件的路径复制,并添加到环境变量中即可,

添加到环境变量

win+s搜索编辑系统环境变量,点击第一个搜索结果后,点击环境变量按钮,选中上方用户变量中的PATH(python安装时默认添加到系统的的那个环境变量名称) 点击编辑按钮进入到PATH中。

将刚刚下载好的edgedriver.exe的路径复制到里边,然后点击三个已经打开的窗口的确定,退出设置系统环境变量的窗口后,至此已将edgedriver的路径添加到了环境变量中。我们可以使用python代码来进行web自动化了

selenium教程

以下的python selenium代码和操作技巧是作者本人在进行web自动化过程中常用到的一些基本方法,基本涵盖了常见操作。

导入的库

python 复制代码
from selenium import webdriver#webdriver对象
from selenium.webdriver.edge.options import Options#options选项因webdriver类型而异,这里使用edge
from selenium.webdriver.common.by import By#定位元素By类
from selenium.webdriver.common.keys import Keys#模拟按键操作Keys类
from selenium.webdriver.support.ui import WebDriverWait#显性等待
from selenium.webdriver import ActionChains#用来模拟人为操作鼠标的一系列动作
from selenium.webdriver.support import expected_conditions as EC#条件等待,配合显性等待使用
from selenium.common.exceptions import TimeoutException#超时错误
from selenium.common.exceptions import NoSuchElementException#元素定位错误

设置webdriver对象

python 复制代码
browser=webdriver.ChromiumEdge()#设定一个webdriver对象,Edge浏览器
browser=webdriver.Chrome()#设定一个webdriver对象,Chrome浏览器
browser=webdriver.Firefox()#设定一个webdriver对象,Firefox浏览器

这里需要注意的是,要使用哪一个类型的浏览器作为webdriver,那么我们需要下载该浏览器的driver.exe文件,并按照之前的流程将其添加到环境变量中,这里我们使用Edgedriver,故webdriver对象是ChromiumEdge()

设定options

selenium中的options是用来设定浏览器的一些属性和必要的操作选项的。

同样的,options也因浏览器的类型而异,导入时也应该按照你的webdriver类型选择

python 复制代码
from selenium.webdriver.firefox.options import Options#火狐浏览器
from selenium.webdriver.edge.options import Options#Edge浏览器
from selenium.webdriver.chrome.options import Options#Chrome浏览器

以下是一些常见的options选项(主要是用来隐藏自动化控制的痕迹并且设置文件下载路径)

python 复制代码
options=Options()#先声明一个options变量
Options.add_argument('--disable-blink-features=AutomationControlled)#隐藏自动化控制标头
Option.add_experimental_option('excludeSwitches',['enable-automation'])#隐藏自动化标头
Options.add_argument('--ignore-ssl-errosr')#忽略ssl错误
Options.add_argument('--ignore-certificate-errors')#忽略证书错误
prefs = {
     'download.default_directory': '文件夹路径',  # 设置文件默认下载路径
     "profile.default_content_setting_values.automatic_downloads": True  # 允许多文件下载
 }
 options.add_experimental_option("prefs", prefs)#将prefs字典传入options

最后,我们需要将已经设定好的options传入到先前设定的webdriver对象中

python 复制代码
browser=webdriver.ChromiumEdge(options)#将options传入到webdriver中

这样,我们便可以使用browser(已经设定好的options 的webdriver对象进行web自动化时,浏览器就会带有options中的特性了)进行后续自动化流程了。

打开网页

接着我们使用已经配置好的webdriver使用get方法即可打开网页

python 复制代码
url=''
browser.get(url)

查找和定位元素

查找元素

selenium中查找元素有两种方法:find_element()与find_elements()

使用find_element或find_elements方法时,其内部第一个参数为定位方式,使用By类下的8个属性指明,后边紧跟着的是元素的在html页面中的定位值,类型为字符串。

python 复制代码
browser.find_element(By.XPATH,'')#根据条件查找单个元素,返回结果为webelement
python 复制代码
browser.find_elements(By.XPATH,'')#查找所有符合条件的元素,返回结果为webelement构成的列表

特别地,在使用find_elements方法时,它会返回所有匹配给定定位器和值的元素列表。如果没有找到任何元素,它将返回一个空列表。这与find_element方法不同,后者在找不到元素时会抛出NoSuchElementException异常。因此,在使用find_elements方法时,我们需要检查返回的列表是否为空,以避免出现错误。

同时,selenium还支持链式查找,即:你可以在查找到一个顶层元素后,直接对该元素使用find_element()和find_elements()方法来定位其内部的子元素。

python 复制代码
top_element=browser.find_element(By.ID,'')
sub_elements=top_element.find_elements(By.TAG_NAME,'')
定位元素

selenium定位元素时共有八种方式:

python 复制代码
brwoser.find_element(By.XPATH,'')#根据元素xpath定位元素,因为获取简单,所以用的最多
brwoser.find_element(By.CSS_SELECTOR,'')#根据元素的css_selector定位,因为获取简单,用的最多
#除xpath和css-selector是可以在浏览器直接复制得到以外,其余定位方法都需要观察html源代码来定位
brwoser.find_element(By.ID,'')
brwoser.find_element(By.CLASS_NAME,'')
brwoser.find_element(By.PARTIAL_LINK_TEXT,'')
brwoser.find_element(By.LINK_TEXT,'')
brwoser.find_element(By.TAG_NAME,'')
brwoser.find_element(By.NAME,'')
XPATH和CSS_SELECTOR 定位

XPATAH和CSS_SELECTOR,在浏览器中打开开发者工具,找到指定元素后,右击,点击复制,便可以直接复制该元素的XPATH和CSS_SELECTOR路径用于定位。

python 复制代码
#复制到的XPATH用于定位
element=browser.find_element(By.XPATH,'//*[@id="home-content-box"]/div[3]/div[2]/div[5]/div/div/div/div/a[1]')
python 复制代码
#复制到的CSS_SELECTOR用于定位
element=browser.find_element(By.CSS_SELECTOR,'#home-content-box > div.home-article > div.home-article-cont > div:nth-child(5) > div > div > div > div > a.article-title.word-1')
ID定位

使用ID定位元素时需要待定位元素具有id属性才可以,id属性通常在Input输入框和Button按钮这两个组件中较为常见。

该组件为一个id为"toolbar-search-button"名为搜索的按钮,那么我们在定位该元素时便可以

python 复制代码
search_button=browser.find_element(By.ID,'toolbar-search-button')
search_button.click()#点击search_button
CLASS_NAME定位

同样的,使用CLASS_NAME定位元素时,元素需要具有class_name属性,一般来说class_name在html中常见于div标签(盒子)。

上边是一些由div组件构成的新闻列表,我们想要获得每个div组件内的所有新闻名称,即每个div元素的text属性,那么便可以使用class_name的定位方式。

python 复制代码
divs=brower.find_elements(By.CLASS_NAME.'headswiper-item')#定位到所有div
titles=[div.text for div in divs]#在所有div中遍历获取text属性
print(titles)#打印结果

结果:

LINK_TEXT与PARTIAL_LINK_TEXT在定位元素时主要根据链接的全部文本或部分文本进行定位。LINK_TEXT指的是完整的链接文本,而PARTIAL_LINK_TEXT则是链接文本的一部分。

例如,如果页面中有一个链接是"点击这里访问百度",那么可以使用LINK_TEXT('点击这里访问百度')或PARTIAL_LINK_TEXT('点击这里')来定位这个链接。这种定位方式对于页面中的链接元素非常有效,尤其是当链接文本较为独特,不容易与其他元素混淆时。

这里我们以csdn网页中的最顶层一栏为例

对于顶层一栏中的下载文本,在开发者工具中观察其原码,我们不难发现这就是一个典型的LinkText,并且当我们点击这个文本后,页面便会跳转到新的链接。对此,我们便可以使用LINK_TEXT方法定位。

python 复制代码
download=browser.find_element(By.LINK_TEXT,'下载')
download.click()#点击下载文字
TAG_NAME定位

TAG_NAME是HTML标签的名称,通过元素的标签名来定位元素时,若html中不止一个元素具有此标签名的话,我们通常使用find_elements()函数查找。

python 复制代码
essay_container=browser.find_element(By.XPATH,'//*[@id="new-article-list"]/div/ul ')#这是一个存放多篇论文题目与跳转链接的div容器
essaies=essay_container.find_elements(By.TAG_NAME,"li")#在div容器中遍历查找tagname是li的元素
essay_titles=[essay.text for essay in essaies]#遍历essaies内所有元素,使用text方法获取essay题目
NAME定位

NAME定位是通过元素的name属性来定位元素。在HTML中,一些元素如input、select等都可以设置name属性。使用NAME定位时,我们只需传入元素的name属性值即可。

python 复制代码
input=browser.find_element(By.NAME,'username')#定位NAME属性为username的输入框
input.send_keys('user')#向输入框内填写user
总结

在使用selenium定位元素时,最简单好用的是XPATH和CSS_SELECTOR,因为其获取方式简单,但是XPATH和CSS_SELECTOR,在定位速度上不如ID等其他定位方式,因为ID和其他的定位方式都是html元素的属性,其在DOM树中是唯一的,查找速度最快。

同时,还有一点值得注意的是,虽然XPATH和CSS_SELECTOR可以非常灵活地定位页面元素,但是在一些复杂的页面中,XPATH和CSS_SELECTOR可能会变得非常冗长和复杂,且由于网页内容的变动二者也会随之产生变化,这会增加代码的复杂性和维护难度。

因此,在进行web自动化任务时我们应该先观察网页原码,定位元素时尽量先考虑使用元素的属性来进行定位,实在找不到再使用XPATH和CSS_SELECTOR对其进行定位。

webDriver常用方法

打开网页

python 复制代码
browser.get(url)#打开网页

获得当前浏览器界面内打开过的所有窗口句柄列表

python 复制代码
browser.window_handles#获得当前所有打开的窗口句柄,是一个列表,获得最新的当期界面可以用

利用browser.window_handles切换当前窗口至最新打开的窗口

python 复制代码
#利用browser.window_handles切换当前窗口至最新打开的窗口
Latest_window=browser.window_handles[-1]
browser.switch_to.window(Latest_window)

切换到iframe

python 复制代码
browser.switch_to.frame()#切换到iframe

给当前webdriver添加cookie

python 复制代码
browser.add_cookie()#给当前webdriver添加cookie,通常出现在免登录情境下

获得当前页面url的cookies

python 复制代码
browser.get_cookies()#获得当前页面url的cookies

删除当前webdriver已经添加过的所有cookies

python 复制代码
browser.delete_all_cookies()#删除当前所有cookies

回退至上一个窗口

python 复制代码
browser.back()#回退至前一个窗口

关闭当前窗口

python 复制代码
browser.close()#关闭当前窗口

获得当前窗口的url

python 复制代码
browser.current_url()#返回当前窗口的url

获得当前的窗口句柄

python 复制代码
browser.current_window()#获得当前的窗口句柄,常与browser.switch_to.window()配合使用

在当前页面内执行js脚本

python 复制代码
browser.execute_script()#在当前页面内执行js脚本,传入参数是js代码的字符串形式

在当前页面内执行异步js脚本

python 复制代码
browser.execute_async_script()#在当前页面内执行异步js脚本

向元素输入指定内容

python 复制代码
send_keys()#用来向一个输入框输入字符串
Input_element=browser.find_element(By.XPATH,'')
Input_element.send_keys('待输入内容')

模拟元素被按下键盘上的指定按键

python 复制代码
Send_keys(Keys.按键名称(英文单词大写))#可以模拟按下键盘上的某个按键
#使用Keys需要from selenium.webdriver.common.keys import Keys
Input_element.send_keys(Keys.ENTER)#按下enter健

页面截图

获取当前网页页面截图有以下3种方法:

python 复制代码
browser.get_screenshot_as_png()
browser.get_screenshot_as_base64()
browser.get_screenshot(filename)

用法详解:

python 复制代码
pic_data=browser.get_screenshot_as_png()
#使用get_screenshot_as_png获得的是当前页面截图的bytes型数据
#若要保存至本地需要使用with open语句写入
with open('页面截图.png','wb') as f:
    f.write(pic_data)

base64_string=browser.get_screenshot_as_base64()#直接返回页面截图的base64字符串

browser.get_screenshot(filename)#直接将页面截图保存到本地,需要传入一个filename参数,注意文件名的结尾必须是.png否则会引发warning

元素截图

获取某个元素的截图有以下3种方法:

python 复制代码
element.screenshot_as_png
element.screenshot_as_base64
element.screenshot(filename)

用法详解:

python 复制代码
element=browser.find_element(By.XPATH,'')

pic_data=element.screenshot_as_png
#使用screenshot_as_png获得的是图片的bytes型数据,若要保存本地需要with open保存
with open('filename.png','wb') as f:
    f.write(pic_data)

base64_sring=element.screenshot_as_base64#直接返回元素截图的base64字符串

element.screenshot(filename)#直接将元素截图保存到本地,需要传入一个filename参数,注意文件名的结尾必须是.png否则会引发warning

关闭webdriver

python 复制代码
browser.quit()
python 复制代码
button=browser.find_element(By.XPATH,"")#假设我们查找到一个按钮
在使用button.click()时可能会出现报错:element click intercepted exception,这时我们使用下边这行代码,可以解决这个问题
browser.execute_script('arguments[0].click()',button)#即执行点击按钮的js代码

等待机制

在使用selenium进行web自动化任务时,有三种等待机制,隐性等待,显性等待,以及time.sleep

隐形等待

implicately_wait

python 复制代码
browser.implicately_wait(秒数)

等待页面内的元素在dom中出现,在全局中只需要设定一次即可,不需要到处写

显性等待

WebdriverWait,可以结合expected_conditions查找元素时进行条件等待

python 复制代码
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

#最多等待10秒直到元素出现
#等待时间内没有找到元素超时会抛出TimeoutException
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH,'')))

#还可以等待这个元素不出现
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH,'')))
#等待时间内找到元素超时会抛出TimeoutException

#二者唯一的区别是until和until_not

time.sleep

这个最常用,他的作用就是阻塞当前程序内线程,让整个程序停下来,等待打开的webdriver内的元素加载完毕,相较于implicately_wait不具有太多的灵活性,但确实是最稳定的等待机制。

使用时需要

python 复制代码
import time
time.sleep(秒数)

异常处理机制

在selenium进行web自动化任务过程中,最常见的两个异常分别是:NoSuchElementExecption与TimeoutException。

其中,TimeoutException主要出现在显性等待元素中,NoSuchElementExecption主要出现在find_element的失败情况中。对此,我们使用try except语句捕获异常进行处理即可,不过,在这之前我们需要先从selenium内的exceptions模块中导入这两个异常

python 复制代码
from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import NoSuchElementException
python 复制代码
try:
    element=browser.find_element(By.XPATH,'')
    element.click()
except NosuchElementException:
    print('无法找到该元素!')
    browser.quit()

Actionchains常用方法

首先,我们需要将Actionchains导入并与webdriver绑定

python 复制代码
from selenium.webdriver import ActionChains
action=ActionChains(browser)#绑定之前的webdriver

接着对于action,我们便可以用来模拟鼠标的一系列复杂动作,如拖动、点击、双击、悬停等。

假设我们已经定位到一个元素

python 复制代码
element=browser.find_element(By.XPATH,'')

鼠标左键单击元素

python 复制代码
action.click(element).perform()

鼠标右键单击元素

python 复制代码
action.context_click(element).perform()

鼠标移动并悬停在元素

python 复制代码
action.move_to_element(element).perform()

鼠标左键单击长按一个元素

python 复制代码
action.click_and_hold(element).perform()

双击元素

python 复制代码
action.double_click(element).perform(

将元素1拖动到元素2上(比如:上传文件)

python 复制代码
action.drag_and_drop(element1,element2).perform()

模拟鼠标从当前位置按照偏移量移动到指定位置

python 复制代码
action.move_by_offset(xoffset,yoffset).perform()

将一个元素按照指定偏移量拖转到目的地(滑块验证)

python 复制代码
action.drag_and_drop_by_offset(element,xoffset,yoffset).perform()

点击元素时出现 element click intercepted exception的两个解决办法

1.使用webdriver的execute_script()方法执行"arguments[0].click()"这个js代码

python 复制代码
button=browser.find_element(By.XPATH,"")#假设我们查找到一个按钮
在使用button.click()时可能会出现报错:element click intercepted exception,这时我们使用下边这行代码,可以解决这个问题
browser.execute_script('arguments[0].click()',button)#即执行点击按钮的js代码

2.使用ActionChains 的模拟鼠标移动到元素上后单击

python 复制代码
action.move_to_element(element).click(element).perform()

结束:

以上便是作者本人关于python Selenium在web自动化中的使用方法与常用技巧的总结。当然,Selenium的功能远不止于此,它还有许多高级特性和用法等待我们去探索和掌握。但无论如何,掌握以上这些基础知识和技巧,已经能够帮助我们解决大部分Web自动化测试中的问题了。希

望这篇文章能够对正在学习python Selenium的你有所帮助,让你在Web自动化的道路上越走越远。

相关推荐
莫忘初心丶1 分钟前
python flask 使用教程 快速搭建一个 Web 应用
前端·python·flask
不爱学英文的码字机器33 分钟前
Python爬虫实战:从零到一构建数据采集系统
开发语言·爬虫·python
鹿鸣悠悠39 分钟前
Python 类和对象详解
开发语言·python
laocooon52385788644 分钟前
用Python实现的双向链表类,包含了头插、尾插、归并排序等功能
开发语言·python
百锦再1 小时前
在Linux上创建一个Docker容器并在其中执行Python脚本
linux·python·docker
东方芷兰2 小时前
伯克利 CS61A 课堂笔记 12 —— Syntax
笔记·python
龙虎榜小红牛系统2 小时前
Python项目源码34:网页内容提取工具1.0(Tkinter+requests+html2text)
python·requests
湘淮子2 小时前
使用S32DS部署Tensorflow lite到S32K3
人工智能·python·tensorflow·s32ds·s32k3
大数据追光猿2 小时前
【深度学习】Pytorch的深入理解和研究
人工智能·pytorch·python·深度学习·机器学习·ai编程
阿正的梦工坊2 小时前
PyTorch gather 方法详解:作用、应用场景与示例解析(中英双语)
人工智能·pytorch·python