UI自动化-Selenium

目录

前言

只需安装两个库

浏览器和驱动

浏览器操作

定位元素

八大定位

特殊元素定位

① select下拉框定位及相关操作

② 弹窗定位及相关操作

③ iframe内嵌框架定位及相关操作

④ 文件的上传下载

上传

绝对路径上传

相对路径上传

下载

firefox下载

chrome下载

元素操作

鼠标&键盘事件

鼠标操作

键盘操作

三大等待

文本验证码识别

截屏


前言

我一直很喜欢它, 但总觉得用不上, 感觉它很没用..., 因为它要看这个电脑本地的网速、浏览器、配置等等各种环境吧, 我一直觉得它很慢, 用起来很不爽, 体验比较差, 等待的时间还不如我直接去手动操作?

只需安装两个库

pip3 install selenium
pip3 install webdriver-manager

浏览器和驱动

BB:

我可能是写自己的记录, 也想把自己当时的想法写出来, 所以经常多BB两句, 就当是讲故事了, 给以后的自己看也行:  一开始呢做的WEB自动化都用chrome、firefox浏览器, 这两个浏览器我好奇到底都是谁在用? chrome还偶尔见, 火狐根本没见过...... 常见的都是些什么360、夸克、2345、QQ等浏览器, 不过那些浏览器都套chrome的内核, 所以才自动化都用chrome吧?  我个人不喜欢chrome界面, 平时用Edge较多, 也省的下载了

浏览器驱动:

在Selenium4.0之前, 想要控制什么浏览器, 都得去找对应浏览器版本的驱动, 算是比较麻烦, 现在方便了, 多安装一个webdriver_manager的库, 就可以自动下载对应的驱动

# 导入selenium的web驱动
from selenium import webdriver
# 导入selenium的chrome服务
from selenium.webdriver.chrome.service import Service

# 导入驱动管理的chrome管理
from webdriver_manager.chrome import ChromeDriverManager


# 获取chrome驱动
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

"""
写了这么多遍老是记不住, 我人麻了, 主要每次都不是自己手动写的
要么是直接复制改一下名字, 要么是编辑器快捷输入....

官网是这么说的, 牛B的可以了解了解...
https://www.selenium.dev/documentation/selenium_manager/
大概就是说: 升级到selenium4之后, 可以用webdriver_manager直接下载对应浏览器驱动, 
避免了版本不同驱动不兼容问题

Edge的话不一样, 之前好像在哪看到过, 说selenium4自带edge驱动还是啥的? 不用另外
安装可以直接用, 所以我更喜欢用Edge...
"""
"""
更多浏览器例子看别人文章, 
https://blog.csdn.net/weixin_47754149/article/details/128502965
"""

也附上一些下载地址吧, 可能用得上

1. chrome旧驱动
    chrome新驱动和浏览器 - 正式版、测试版、开发版

2. 火狐驱动

浏览器操作

① webdriver内置方法

from selenium import webdriver
from time import sleep


# 获取驱动
driver = webdriver.Edge()

# 打开网址
driver.get("https://www.baidu.com")
sleep(2)

# 打开网址2
driver.get("https://cn.bing.com/")
sleep(2)

# 退回一个页面
driver.back()
sleep(2)

# 前进一个页面
driver.forward()
sleep(2)

# 刷新页面
driver.refresh()
sleep(2)

# 全屏
driver.fullscreen_window()
sleep(2)

# 最小化窗口
driver.minimize_window()
sleep(2)

# 最大化窗口
driver.maximize_window()
sleep(2)

# 获取浏览器窗口大小
size = driver.get_window_size()
print("浏览器窗口大小: ",size)
sleep(2)

# 设置浏览器窗口大小
driver.set_window_size(1700,1000)
sleep(2)

# 获取浏览器窗口位置
position = driver.get_window_position()
print("浏览器默认位置",position)

# 设置浏览器窗口位置
driver.set_window_position(480,270)
sleep(2)

# 获取当前页面的title
title = driver.title
print("当前页面的title",title)

# 获取当前URL
current_url = driver.current_url
print("当前的当前URL",current_url)

# 当前页面的源码....
is_page_source = driver.page_source

# 进入使用click()点击超链接元素打开一个网址
driver.find_element("css selector","#trending_now_tile > li:nth-child(1) > a > span > img").click()
sleep(2)

# 生成所有句柄, 句柄可以理解为当前所有已打开的网址
n = driver.window_handles
# 切换到当前最新打开的网页
driver.switch_to.window(n[-1])
# 关闭当前窗口
driver.close()
sleep(2)

"""
还有一个是send_keys(str), 作用是定位到input输入框之后,可以在里面输入内容
"""

#退出浏览器
driver.quit()

② 操作滚动条

操作内嵌iframe框架里的滚动条 or 整个窗口的滚动条

from time import sleep
from selenium import webdriver

# 获取谷歌驱动
driver = webdriver.Edge()
# 打开网址
driver.get("http://sahitest.com/demo/iframesTest.htm")
# 隐式等待
driver.implicitly_wait(10)

# 进入第一个内嵌iframe
driver.switch_to.frame(0)
# 强制等待
sleep(2)
# 编写js脚本滑动向下和右200px
down_rit200 = "window.scrollTo(200,200)"
# 执行脚本
driver.execute_script(down_rit200)
# 强制等待
sleep(2)
# 向上和左滑动
up_lft200 = "window.scrollTo(-200,-200)"
driver.execute_script(up_lft200)
# 强制等待
sleep(2)

# 退出iframe
driver.switch_to.default_content()
"""
还有其他脚本定位方式, 喜欢哪个用哪个, 我选简单的..
# 上下左右
down200 = "document.documentElement.scrollTop=200"
up200 = "document.documentElement.scrollTop=-200"
right200 = "document.documentElement.scrollLeft=200"
left200 = "document.documentElement.scrollLeft=-200"
"""

操作元素上的滚动条,比如div的滚动条, 懒得写, 放个图片吧

定位元素

八大定位

此处用百度首页举例, 定位百度首页的'百度一下'按钮

①使用ID定位

from selenium import webdriver

# 获取驱动
driver = webdriver.Edge()

# 打开网址
driver.get("https://www.baidu.com")

# id定位
driver.find_element("id","su")

②使用xpath定位

# 根据元素属性值定位
driver.find_element("xpath", "//input[@id='su']")

# 根据元素文本值, 定位百度首页的 '新闻'
driver.find_element("xpath", "//a[text()='新闻']")

③使用link text定位, 这个只能定位带文本的超链接元素

# 定位百度首页的'新闻'链接
driver.find_element("link text", "新闻")

④使用partial link text定位, 这个可以模糊定位带文本的超链接元素,

# 定位百度首页的 hao123 文本超链接元素, 模糊定位, 输入部分内容就行
driver.find_element("partial link text", "a123")

⑤使用name定位, 和id一样, 有name直接写就行了

⑥使用tag name定位

# 定位第一个input元素
driver = find_element("tag name", "input")

"""
使用tag name定位, 很容易遇到很多个相同标签, 可以这么写:

driver = find_elements("tag name", "input")

加个s代表复数, 这样就可以定位页面所有的input标签, 
可以使用for循环遍历选择对应的...基本没啥用, 几乎没用过...

没错, 如果有的话, 其他几种定位方式也可以通过加s来定位多个...
八大定位 ×
十六定位 √
"""

⑦使用class name定位

# 定位百度首页搜索框
driver.find_element("class name", "s_ipt")

⑧使用css selector定位

# 定位百度首页的'百度一下'按钮
driver.find_element("css selector", "#su")

"""
css选择器定位就是要在前面加个#号

相对路径: 可以先找到距离当前元素最近的唯一属性比如id, 然后根据层级定位

和xpath一样, 也可以使用绝对路径:从根目录html开始, 不过应该没谁会这样做吧, 太麻烦
"""

终于写完了, 8个定位, 感觉有些不常用的都忘了, 还是百度了下才想起...

特殊元素定位

特殊元素也不是元素特殊, 只是有些元素是8种定位方式定位不到的...... 
select下拉框、alert / confirm / prompt三种弹窗定位、frame框架定位等

① select下拉框定位及相关操作
from selenium import webdriver
from time import sleep
# 导入定位select标签专用包
from selenium.webdriver.support.select import Select

# 获取驱动
driver = webdriver.Edge()

# 进入一个带下拉框的网址
driver.get("https://sahitest.com/demo/selectTest.htm")

# 定位到select元素
selects = Select(driver.find_element("id","s4Id"))
# 元素判断是否支持多选 is_multiple
print(selects.is_multiple) # 返回True
# 查看元素有几个选项
print(selects.options) # 是个列表, 可以选择print(len(selects.options))

# 既然支持多选,试试多选, 有多种选择方式
selects.select_by_index(1) # 用索引选, 索引从0开始
sleep(1)
selects.select_by_value('o3val') # 用属性value选
sleep(1)
selects.select_by_visible_text("") # 用页面文本选
sleep(2)
#选择后想取消选择, 取消索引1的, 就是在 选中方法 的前面加上 de
selects.deselect_by_index(1)
sleep(2)
# 直接取消所有的
selects.deselect_all()


# 再定位一个单选的 select元素
select = Select(driver.find_element("css selector","#s2Id"))
# 判断是否支持多选
print(select.is_multiple)
# 用索引选中第3个
select.select_by_index(2)
sleep(1)
# 取消选中的, 单选的不能被取消,只能重新换选中位置
# 用文本选第一个
select.select_by_visible_text("")
sleep(2)
driver.quit()
② 弹窗定位及相关操作

弹窗的话js中常见的有3种弹窗

第一种: alert() 警告窗

from selenium import webdriver
from time import sleep

# 获取驱动
driver = webdriver.Edge()
# 进入网址
driver.get("https://sahitest.com/demo/alertTest.htm")

# 获取元素
alert = driver.find_element("name","b1")

# 点击元素
alert.click()
sleep(2)

# 打印元素对象信息
print("弹窗元素对象信息", driver.switch_to.alert)
# 打印元素文本内容
print("打印alert弹窗内容:", driver.switch_to.alert.text)

# 点击弹窗上的确定按钮
driver.switch_to.alert.accept()

# # 点击提示框的取消..虽然alert提示框没有取消按钮, 这里选择取消也可以..
# driver.switch_to.alert.dismiss()
sleep(2)

第二种: confirm() 确认窗

from selenium import webdriver
from time import sleep

# 获取驱动
driver = webdriver.Edge()

# 进入 弹窗 确定取消 的网址
driver.get("https://sahitest.com/demo/confirmTest.htm")

# 获取confirm弹窗按钮
confirm = driver.find_element("name","b1")
# 点击弹窗
confirm.click()
sleep(2)

# 点击确定按钮取消
driver.switch_to.alert.accept()
sleep(2)

# 再次点击弹窗
confirm.click()
sleep(2)
# 点击取消按钮取消
driver.switch_to.alert.dismiss()
sleep(2)

第三种: propmt() 输入窗

遇到点问题..., 原本确实是用'switch_to.alert.send_keys()'方法给输入框输入内容的,
不知为什么输入不了..., 输入到下一个input框了...

from selenium import webdriver
from time import sleep

# 获取驱动
driver = webdriver.Edge()

# 获取 输入弹窗 的网址
driver.get("https://sahitest.com/demo/promptTest.htm")


# 获取弹窗按钮
prompt = driver.find_element("name","b1")

sleep(2)
# 点击弹窗
prompt.click()
sleep(1)
# 输入内容
driver.switch_to.alert.send_keys("本次点击的是确定按钮,下次是取消")
sleep(2)
# 点击确定按钮
driver.switch_to.alert.accept()
sleep(1)

# 再次点击输入弹窗
prompt.click()
sleep(1)
# 输入内容
driver.switch_to.alert.send_keys("我要点击取消按钮了")
sleep(2)
# 点击取消
driver.switch_to.alert.dismiss()
sleep(2)
③ iframe内嵌框架定位及相关操作
from time import sleep
from selenium import webdriver

"""
有时定位一个元素, 比如用id, 明明没输错, 但就是定位不到?
这就很奇怪了, 最直接的id都定位不到, 还有别的能定位到吗?

这时可以看看元素上面的标签, 很可能是写在iframe框架中的
这个一般在登录窗口比较常见, 相当于是打开了一个新的页面
所以需要先进入这个新页面, 才能继续定位这个页面中的元素
操作完成后记得退出新页面, 才能继续操作之前页面的元素哦
"""

# 定位iframe框架有三种方式, 分别是使用索引、id、web元素对象
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By

# 获取驱动
driver = webdriver.Edge()
# 打开网易邮箱首页
driver.get("https://mail.163.com/")
# 使用索引的方式获取并进入iframe内嵌框架
driver.switch_to.frame(0)
"""
其他方式:
# 直接填入iframe框架的id值
driver.switch_to.frame(id) 
# 直接填入iframe框架的name值
driver.switch_to.frame(name) 
# 也可以先用8大定位方式定位到iframe元素, 然后直接放入这个web元素
driver.switch_to.frame(driver.find_element('method', 'path')) 

"""
sleep(1)
# 获取登录邮箱输入框
driver.find_element(By.NAME,"email").send_keys("123")
# 获取登录密码输入框
sleep(1)
driver.find_element(By.NAME,"password").send_keys("哈哈")

# 假装已经点击登录按钮
sleep(2)

# 退出iframe框架
driver.switch_to.default_content()
"""
也可以获取当前所有句柄, 然后进行切换句柄..
# 获取所有句柄
all_handles = driver_gl.window_handles
# 退出到第一个界面: 获取所有句柄后返回的是个列表, 这里用切片的方式选择第一个网页窗口
driver.switch_to.window(all_handles[0]) 
"""
# 再尝试定位底部的'网易首页'超链接
driver.find_element(By.PARTIAL_LINK_TEXT,"易首页").click()
sleep(2)

④ 文件的上传下载

我一直在想把这个文件上传下载归类到 [浏览器操作] 还是放入 [元素定位] 里面..., 
既然写到这里才想起来, 那就先放这吧

上传
绝对路径上传
from selenium import webdriver
from time import sleep

"""文件上传"""
# 获取驱动
driver = webdriver.Edge()
driver.get("https://sahitest.com/demo/php/fileUpload.htm")
# 定位所有name为file的上传按钮
files_button= driver.find_elements("name","file")
# 使用for循环挨个上传, 每上传一个, 等1秒
for i in files_button:
    # 使用绝对路径上传  !!!send_keys只能对input元素有效!!!
    i.send_keys(r"C:\Test\ALL\demo.py")
    sleep(1)
sleep(3)
相对路径上传
from selenium import webdriver
from time import sleep
import os

"""文件上传"""
# 获取驱动
driver = webdriver.Edge()
driver.get("https://sahitest.com/demo/php/fileUpload.htm")

"""
相对路径,需要采用os模块里的path相关函数
    语法说明:
    os.path.join()                 拼接路径的,每级目录之间用,隔开
    os.path.dirname(os.getcwd())   返回到当前文件所在目录的上一级
    os.getcwd()                    
    print(os.getcwd())             打印 当前文件所在的目录

"""
# 设置文件及路径
filepath = os.path.join(os.getcwd(), "demo.py")
# filepath = os.path.join(os.path.dirname(os.getcwd()), "230203.py")

driver.find_element("id","file").send_keys(filepath)
sleep(2)
sleep(2)

我觉得这个文件上传下载比较鸡肋? 因为文件上传的话, 需要网页用的是input元素才能上传
而文件下载..确定可以让他下载, 但是不知道到底有没有下载完成?

下载

下载使用的是浏览器配置项进行下载的, 每个浏览器不一样

firefox下载

(这个没具体试过, 因为我不喜欢火狐, 没他的浏览器

from webdriver_manager.firefox import GeckoDriverManager
from selenium.webdriver.firefox.service import Service
from selenium import webdriver
from time import sleep
import os



"""
    火狐浏览器
操作步骤:
    1 创建Firefox浏览器配置信息对象
      webdriver.FirefoxProfile()
    2 设置Firefox浏览器下载相关的自定义配置信息
    3 设置Firefox浏览器对象,并把自定义配置信息存储到浏览器对象中
    4 访问下载网站进行下载
"""
# 1. 创建火狐浏览器配置信息对象,用于存放自定义配置
options = webdriver.FirefoxOptions()

# 2. 配置Firefox下载相关信息
"""
2.1
指定自定义下载路径,默认只会自动创建一级的目录,
如果指定了多级不存在的目录,就会下载到默认路径
"""
options.set_preference("browser.download.dir","D:\\FF_Download\\")
"""
2.2
将browser.download.folderList设置为:
    设置成 0 表示下载到桌面
    设置成 1 表示下载到浏览器默认下载路径
    设置成 2 表示使用自定义下载路径
    和上面browser.download.dir配合使用, 如果设置成0或1,上面的自定义路径配置基本无用
"""
options.set_preference("browser.download.folderList", 2)

"""
2.3
browser.helperApps.alwaysAsk.force:
    对未知的 mime 类型文件会弹出窗口让用户处理
    默认值为true,
    设定为False表示不会记录打开未知 MIME 类型文件的方式
"""
options.set_preference("browser.helperApps.alwaysAsk.force",False)

"""
2.4
browser.download.manager.showWhenStarting
在开始下载时是否显示下载管理器
    设定为True,则在用户启动下载的时候显示Firefox浏览器的文件下载窗口
    否则不显示文件下载窗口
"""
options.set_preference("browser.download.manager.showWhenStarting",False)

"""
2.5
browser.download.manager.useWindow
设定为 False 会把下载框进行隐藏
"""
options.set_preference("browser.download.manager.useWindow",False)

"""
2.6 
browser.download.manager.focusWhenStarting
默认值为True,表示获取焦点
"""
options.set_preference("browser.download.manager.focusWhenStarting",False)

"""
2.7
browser.download.manager.alertOnEXEOpen
下载.exe文件弹出警告
默认值是True,设置为False则不会弹出警告框
"""
options.set_preference("browser.download.manager.alertOnEXEOpen",False)

"""
2.8
browser.helperApps.neverAsk.openFile:
    表示直接打开下载文件,不显示确认框
    默认值为空字符串,下行代码行设定了多种的 MIME类型,
    例如:
        application/exe    表示 .exe 类型的文件,
        application/execel 表示 Excel 类型的文件
"""
options.set_preference("browser.helperApps.neverAsk.openFile","application/zip")

"""
2.9
对所给出文件类型不再弹出框进行询问,直接保存到本地磁盘
"""
options.set_preference("browser.helperApps.neverAsk.saveToDisk",
                       "application/zip, application/octet-stream")
"""
其他可选文件类型:
    application/a-gzip
    application/x-gzip
    application/zip
    application/x-gtar
    text/plain
    application/x-compressed
    application/octet-stream
    application/pdf
"""

"""
2.10
browser.download.manager.showAlertOnComplete
    设定下载文件结束后是否显示下载完成提示框
    默认为True
    设定为False表示下载完成后不显示完成提示框
"""
options.set_preference("browser.download.manager.showAlertOnComplete",False)

"""
2.11 
browser.download.manager.closeWhenDone:
    设定下载结束后是否自动关闭下载框,默认值为True
    设置为False,表示不关闭下载框
"""
options.set_preference("browser.download.manager.closeWhenDone",False)


# 创建浏览器对象
driver_ff = webdriver.Firefox(service=Service(GeckoDriverManager().install()),
                              options=options)

# 访问网址
driver_ff.get("https://npm.taobao.org/mirrors/geckodriver/v0.20.0/")
sleep(3)
# 定位下载连接 , 点击下载
file = driver_ff.find_element("link text","geckodriver-v0.20.0-win64.zip")
file.click()
sleep(3)

driver_ff.quit()
chrome下载

因为Edge浏览器用的是chrome内核, 所以我直接用Edge浏览器吧, 不习惯(喜欢)谷歌...

"""Chrome浏览器文件下载
"""
from selenium import webdriver
from time import sleep
import os

# 创建浏览器配置选项
options = webdriver.EdgeOptions()

# 定义加载项参数
prefs = {'profile.default_content_settings.popups': 0,
         'download.default_directory': 'C:\\Users\\nn\Desktop\禁止点击'}
"""
download.default_directory:指定路径
profile.default_content_settings.popups:0 为屏蔽弹窗,1 为开启弹窗
"""
# 将加载项参数添加到浏览器配置选项中
options.add_experimental_option("prefs", prefs)
# 获取驱动, 传入调试项
driver = webdriver.Edge(options=options)

# 打开页面
driver.implicitly_wait(10)
driver.get("https://registry.npmmirror.com/binary.html?path=chromedriver/111.0.5563.19/")

# 点击下载
driver.find_element("link text", "chromedriver_win32.zip").click()
# 给出下载时间.......10秒

"""
刚开始学的时候, 是使用sleep()给出指定的下载时间, 防止浏览器自动关闭
这个我觉得不太智能, 万一因为网络或者什么环境问题, 下载时间到了, 文件却没下载完成,浏览器关闭了怎么办?
之前也有考虑到这个问题, 但是没想到解决办法
"""
"""
现在这么多年会过来看看, 暂时想到的思路就是: 去读取下载目录: 是否存在下载的文件? 如果存在就退出读取任务或关闭浏览器
操作步骤描述:
1. 因为我也不知道具体下载时间,所以这里使用while循环, 为了性能考虑每2秒循环一次吧...
2. 因为返回的对象比较特殊,需要用for循环遍历
3. 遍历后使用if判断指定文件是否已存在该目录, 如果存在就跳出循环
"""
while True:
    sleep(2)
    for i in os.walk("C:\\Users\\nn\Desktop\禁止点击"):
        
        if "chromedriver_win32.zip" in i[2]:
            print("已下载完成")
        break
    break


"""
os.walk(path)参数解读:
    就当他可以遍历一个指定的文件路径
    返回值是个generator对象, 需要用for循环遍历, 遍历后是元组, 有三个参数:
        root  保存当前遍历的文件夹的绝对路径;
        dirs  保存当前文件夹下的所有子文件夹的名称(仅一层,孙子文件夹不包括)
        files 保存当前文件夹下的所有文件的名称
上面代码用切片的形式, 直接返回第三个参数files,是个列表,
判断这个列表是否包含指定名称的文件
"""

元素操作

from time import sleep
from selenium import webdriver

# 获取驱动
driver = webdriver.Edge()

search = driver .find_element("id","kw")
print("元素文本内容",search.text)
print(f"元素名{search.tag_name}")
print("元素大小",search.size)
print("元素的css的width值",search.value_of_css_property("width"))
print("搜索框是否可见",search.is_displayed())
print("搜索框是否可用",search.is_enabled())
search.send_keys(123)
print("搜索框是否被选中",search.is_selected())

driver .quit()

鼠标&键盘事件

鼠标操作

from selenium import webdriver
from time import sleep
from selenium.webdriver.common.action_chains import ActionChains

# 获取驱动
driver = webdriver.Edge()
# 打开控件网址
driver.get("http://sahitest.com/demo/clicks.htm")
# 给动作链指定驱动
ac = ActionChains(driver)
# 定位到鼠标右键按钮
right_click_btn = driver.find_element("css selector","body > form > input[type=button]:nth-child(13)")
# 定位到鼠标双击按钮
db_click_btn = driver.find_element("css selector","body > form > input[type=button]:nth-child(8)")
# 执行鼠标右击右键按钮
ac.context_click(right_click_btn)
sleep(1)
# 执行鼠标双击按钮
ac.double_click(db_click_btn).perform()
sleep(5)

# 切换到拖拽控件页面
driver.get("http://sahitest.com/demo/dragDropMooTools.htm")
# 给动作链重新指定驱动
ac = ActionChains(driver)
# 定位需要拖拽的元素和拖拽到的位置
drag_ele =driver.find_element("id","dragger")
drag_location = driver.find_element("css selector","body > div:nth-child(6)")
# 执行拖拽动作
ac.drag_and_drop(drag_ele,drag_location).perform()
sleep(5)

# 切换淘宝首页
driver.get("https://www.taobao.com/")
# 给动作链指定驱动
ac = ActionChains(driver)
# 定位到需要鼠标悬浮按钮的元素
move_btn = driver.find_element("css selector","#J_SiteNavBdL > li.site-nav-menu.site-nav-switch.site-nav-multi-menu.J_MultiMenu > div.site-nav-menu-hd > span.site-nav-region")
# 执行鼠标悬浮操作
ac.move_to_element(move_btn).perform()
sleep(3)

"""
鼠标操作:
固定写法:
ActionChains.xxx(ele).perform()
# 鼠标左击不松手操作
ActionChains.click_and_hold(test_ele).perform()
# 鼠标右击操作
ActionChains.context_click(test_ele).perform()
# 鼠标指针悬浮操作
ActionChains.move_to_element(test_ele).perform()
# 鼠标拖操作
ActionChains.drag_and_drop(ele, target).perform()

注意: 
1,  每次更换网页后,都要重新给鼠标指定驱动
2,  perform()是鼠标事件的执行方法,鼠标事件刚写上并不会被执行,
    会被放入到一个队列,只有再调用perform()方法后,才会执行这个队列
    (所以这个库叫动作链)
"""

键盘操作

from time import sleep
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
#
#
# 获取谷歌驱动
driver = webdriver.Edge()
# 进入百度首页
driver.get("https://www.baidu.com")

# 找到搜索框
search = driver.find_element("css selector","#kw")
# 搜索框内输入  !23
search.send_keys("!23")
sleep(2)

# 键盘事件 输入框内全选
search.send_keys(Keys.CONTROL,"a")
sleep(2)
# 键盘事件 输入框内剪切
search.send_keys(Keys.CONTROL,"x")
sleep(2)
# 键盘事件,按下回车搜索
search.send_keys(Keys.ENTER)
# 键盘事件,F11全屏,,试过了不行,会报异常, 电脑硬件有关系,每台电脑不一样
# search.send_keys(Keys.F11)
sleep(2)

三大等待

① 强制等待

就是python内置的time包中的sleep()方法, 设置几就强制等几秒, 代码才会继续运行

② 隐式等待

这个隐式等待啊, 当时刚学的时候很喜欢, 每次获取完驱动都要加个隐式等待, 
隐式等待的作用域是全局的, 每有个打开的网址或者刷新什么的都会去有这个隐式等待
缺点是它实在是太慢了, 要等页面所有元素都加载完成, 才会进行下一个操作
selenium本来就慢, 再用这个....我真的...不要说我太着急, 我是吉吉国王, 我太吉了 

from time import sleep
from selenium import webdriver

# 获取驱动
driver = webdriver.Edge()

# 打开网址
driver.get("http://sahitest.com/demo/iframesTest.htm")

# 隐式等待 设置10秒
driver.implicitly_wait(10)

"""
如果超时后还没加载完全, 代码会报异常...
"""

③ 显示等待

显示等待比隐式等待好点, 可以设置等待指定元素加载出来后就继续运行, 超时报异常
但是写起来麻烦, 导的包也多, 写一次也只作用一次, 

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 获取驱动
driver = webdriver.Edge()
# 打开网址
driver.get("http://www.baidu.com")

# 先把驱动加入到显示等待, 再设置等待超时时间比如8秒,
wait = WebDriverWait(driver, 8)
# 定位方式 -- 定位的是搜索框
locator = ("id", "kw")
# 再检查网页上是否至少存在一个搜索框, 如果找到就可以继续运行, 不然超时报错...
ele = wait.until(EC.presence_of_element_located(locator))

"""
显示等待更多使用时的判断条件, 还是看别人写的吧:
https://www.cnblogs.com/yongzhuang/p/15028052.html
"""

文本验证码识别

这个需要新安装一个库ddddocr(带带弟弟ocr),
Github地址:https://github.com/sml2h3/ddddocr,
或者直接使用命令:

pip3 install ddddocr

使用:

import ddddocr
import time
from selenium import webdriver

# 获取驱动
d = webdriver.Edge()

# 打开网址
d.get("https://support.huawei.com/enterprise/ecareWechat")
#
time.sleep(2)
# 处理内嵌
d.switch_to.frame(0)

# 找到验证码图片
img = d.find_element("css selector","#imgObj")


# 获取图片的bytes数据
data = img.screenshot_as_png
# 初始化ocr
ocr = ddddocr.DdddOcr()
# 进行验证码识别
text = ocr.classification(data)
print("验证码是:", text)

# 填写到输入框
d.find_element("css selector","#yzm").send_keys(text)


time.sleep(2)
d.quit()

运行完成后会在控制台发现他给自己打广告了, 哈哈哈, 如果觉得有影响可以进入DdddOcr()源码

把 { if show_ad }下面的 { print(str) } 都删了, 换成pass就行了

截屏

import time
from selenium import webdriver

# 获取驱动
d = webdriver.Edge()

# 打开网址
d.get("https://support.huawei.com/enterprise/ecareWechat")
#
time.sleep(2)
# 处理内嵌
d.switch_to.frame(0)

# 找到确定按钮的元素
img = d.find_element("css selector","#btnSearch")

# 截图浏览器当前窗口保存到本地, 保存格式为png
d.save_screenshot("C:\\Users\\nn\Desktop\禁止点击\\123.png")
# 截图元素保存本地
img.screenshot("C:\\Users\\nn\Desktop\禁止点击\\789.png")


time.sleep(1)
d.quit()

总觉得这样以图片直接结束有点丑, 所以就给底部加了这么一行字。

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值