Python Selenium.WebDriver 清除输入框再输入『详解』
文章目录
一、如何清除输入框中的默认内容
首先,要明确一点的是,Selenium是模拟人们去操作浏览器,它能操作的事大部分都是我们人们能够自己手动实现的事情。
知道这一点后,我们再想想平时浏览网页时遇到存在默认文本内容的输入框时,我们会怎么将其清除掉再输入呢?
- 慢慢敲退格键?虽然麻烦但也是一个方法;
- 拖动并点击鼠标,将默认内容选中后再按退格键将其删除;
- 双击默认文本内容,在选中后的情况下输入我们想要的内容将其替换掉;
- 与双击有着同样原理的是使用
ctrl + a
全选快捷键将其全部选中,这个会比双击能够更可靠地选中默认文本内容,再输入我们想要的内容将其替换掉; - 不断刷新网页,祈祷输入框中的默认文本内容不再出现,哈哈别逗了,这不太可能
二、WebDriverWait 的功能键实现
在上诉的实现方法,都离不开对键盘的操作,全选、回车这些都是需要在代码中去实现,那么如何使用Selenium实现这些操作呢,这就需要用到 Selenium WebDriver 的功能键API(接口)
使用下列导入语句将其导入
from selenium.webdriver.common.keys import Keys
其实源码实现原理很简单,我们来看看源码,只要明白了规则甚至连该模块都不用导入就能实现功能键的输入
class Keys(object):
"""
Set of special keys codes.
"""
NULL = '\ue000'
CANCEL = '\ue001' # ^break
HELP = '\ue002'
BACKSPACE = '\ue003'
BACK_SPACE = BACKSPACE
TAB = '\ue004'
CLEAR = '\ue005'
RETURN = '\ue006'
ENTER = '\ue007'
SHIFT = '\ue008'
LEFT_SHIFT = SHIFT
CONTROL = '\ue009'
LEFT_CONTROL = CONTROL
ALT = '\ue00a'
LEFT_ALT = ALT
PAUSE = '\ue00b'
ESCAPE = '\ue00c'
SPACE = '\ue00d'
PAGE_UP = '\ue00e'
PAGE_DOWN = '\ue00f'
END = '\ue010'
HOME = '\ue011'
LEFT = '\ue012'
ARROW_LEFT = LEFT
UP = '\ue013'
ARROW_UP = UP
RIGHT = '\ue014'
ARROW_RIGHT = RIGHT
DOWN = '\ue015'
ARROW_DOWN = DOWN
INSERT = '\ue016'
DELETE = '\ue017'
SEMICOLON = '\ue018'
EQUALS = '\ue019'
NUMPAD0 = '\ue01a' # number pad keys
NUMPAD1 = '\ue01b'
NUMPAD2 = '\ue01c'
NUMPAD3 = '\ue01d'
NUMPAD4 = '\ue01e'
NUMPAD5 = '\ue01f'
NUMPAD6 = '\ue020'
NUMPAD7 = '\ue021'
NUMPAD8 = '\ue022'
NUMPAD9 = '\ue023'
MULTIPLY = '\ue024'
ADD = '\ue025'
SEPARATOR = '\ue026'
SUBTRACT = '\ue027'
DECIMAL = '\ue028'
DIVIDE = '\ue029'
F1 = '\ue031' # function keys
F2 = '\ue032'
F3 = '\ue033'
F4 = '\ue034'
F5 = '\ue035'
F6 = '\ue036'
F7 = '\ue037'
F8 = '\ue038'
F9 = '\ue039'
F10 = '\ue03a'
F11 = '\ue03b'
F12 = '\ue03c'
META = '\ue03d'
COMMAND = '\ue03d'
键位 | 中文释义 | Unicode码 |
---|---|---|
BACKSPACE / BACK_SPACE | 退格 | \ue003 |
DELETE | 删除 | \ue017 |
HOME | 开头 | \ue011 |
END | 末尾 | \ue010 |
ENTER | 回车 | \ue007 |
CONTROL(CTRL) | 控制(CTRL) | \ue009 |
ALT | ALT | \ue00a |
SPACE | 空格 | \ue00d |
三、退格大法好😍
万能的退格,输入框里有都是内容那就退格多少次,这是一个比较容易想出的方法,相信也有不少人也是一直在使用这个方法
缺点也很明显,比较繁琐,一个两个输入框还好,但如果输入框中的内容有点多,或则输入框的数量有点多,这个方法就不太行了
需要用到退格功能键,我们可以利用Keys包下的 Keys.BACKSPACE
实现或则自行写入Unicode编码 \ue003
即可
思路:
思路很简单,使用get_attribute
方法获取输入框中的内容值,计算其长度并与偏差相加,循环需要摁下的次数并使用send_keys
发送空格
def backspace_clean(element, deviation=3):
"""
退格原理清除输入框中的内容
:param element: 元素
:param deviation: 退格数偏差,默认会多输入3个以确保可靠度
"""
quantity = len(element.get_attribute("value")) + deviation
for _ in range(quantity):
element.send_keys(Keys.BACKSPACE)
将其封装成 清除并输入内容 函数
def backspace_clean(element, deviation=3):
"""
退格原理清除输入框中的内容
:param element: 需要操作的元素
:param deviation: 退格数偏差,默认会多输入3个以确保可靠度
"""
quantity = len(element.get_attribute("value")) + deviation
for _ in range(quantity):
element.send_keys(Keys.BACKSPACE)
def clean_with_send(element, text: str, **kwargs):
"""
清空输入框并且输入内容
:param element: 需要操作的元素
:param text: 输入的内容
"""
backspace_clean(element, **kwargs)
element.send_keys(text)
四、不靠谱的拖动鼠标🤐
如果输入框中的内容较多进行了隐藏或则分了几行,那么可靠度是挺低的。除此之外,还得考虑鼠标的拖动范围,从哪里开始定位,这一系列的动作链操作,编写起来也是比较麻烦的
在开始讲解之前,需要注意三个点:
- 一是鼠标点击操作是在元素的正中间(经过我的测试得出),这就需要先将鼠标移动到元素的开头的进行步骤预处理才行
- 需要事先将浏览器最大化操作
browser.maximize_window()
,如果输入框超出窗口化所显示的范围时候会抛出异常 - 导入Selenium的动作链库再进行代码的编写,
from selenium.webdriver import ActionChains
还需要了解动作链的一些方法,这些方法将在下面的代码中所使用:
方法 | 参数 | 描述 |
---|---|---|
.move_by_offset(xoffset, yoffset) | x 偏移量(横轴),y 偏移量(纵轴) | 鼠标从当前位置移动到某个坐标(x, y)(默认在浏览器左上角,类似网页布局中的固定定位) |
.move_to_element(to_element) | element(目标元素) | 鼠标移动到目标元素中间 |
.move_to_element_with_offset(to_element, xoffset, yoffset) | element(目标元素),x 偏移量(横轴),y 偏移量(纵轴) | 鼠标移动到相对于目标元素的坐标(x, y)「以元素左上角作为参照物」 |
.click_and_hold(on_element=None) | element(目标元素,可选) | 在目标元素下摁下鼠标左键并且不松开。如果没有传入目标元素,则在当前鼠标指针位置下操作 |
.click(on_element=None) | element(目标元素,可选) | 左键点击目标元素。如果没有传入目标元素,则在当前鼠标指针位置下操作 |
.release(on_element=None) | element(目标元素,可选) | 在目标元素处松开鼠标摁键。如果没有传入目标元素,则在当前鼠标指针位置下操作 |
值得注意的是,鼠标移动的位置是继承的,不会移动往后会自动归位到页面左上角。在每次写好 操作设置函数 后要记得加上动作链执行函数
.perform()
,在调用.perform
时,讲连续执行之前所设置的操作设置函数,然后结束
思路:
先获取输入框的大小,确定需要拖动的范围。将鼠标指针移到相当目标输入框(横轴: 1,纵轴: 1)的位置,并摁下左键不松开,移动指针到输入框最右下角的位置并向输入框发送退格功能键,清空内容。最后释放鼠标。
def drag_clean(element, browser):
"""
拖动鼠标原理清除输入框中的内容
:param element: 需要操作的元素
:param browser: 浏览器对象
"""
s_y, s_x = element.size.values()
action = ActionChains(browser)
action.move_to_element_with_offset(element, 1, 1).click_and_hold().perform()
action.move_by_offset(s_x, s_y).send_keys(Keys.BACKSPACE).perform()
action.release() # 释放鼠标
将其封装成 清除并输入内容 函数
def drag_clean(element, browser):
"""
拖动鼠标原理清除输入框中的内容
:param element: 需要操作的元素
:param browser: 浏览器对象
"""
s_y, s_x = element.size.values()
action = ActionChains(browser)
action.move_to_element_with_offset(element, 1, 1).click_and_hold().perform()
action.move_by_offset(s_x, s_y).send_keys(Keys.BACKSPACE).perform()
action.release() # 释放鼠标
def clean_with_send(element, browser, text: str):
"""
清空输入框并且输入内容
:param element: 需要操作的元素
:param browser: 浏览器对象
:param text: 输入的内容
"""
drag_clean(element, browser)
element.send_keys(text)
五、双击后替换😲
双击后替换,这也是一个比较常用的解决方案,但还是存在有可能没选全的情况,因此可以考虑多次双击解决这个问题,代码编写也比较方便,对于简单的输入框还是值得去使用的
导入Selenium的动作链库再进行代码的编写,
from selenium.webdriver import ActionChains
思路:
直接双击输入框,使其内容被选中后向输入框发送退格功能键,清空内容。将上述方法写在循环里,循环次数通过number_of_executions
参数控制,默认值为1次,即执行一次双击清空内容操作。
def double_click_clean(element, browser, number_of_executions=1):
"""
双击内容原理清除输入框中的内容
:param element: 需要操作的元素
:param browser: 浏览器对象
:param number_of_executions: 执行次数,多次执行能有效避免未选全情况
"""
action = ActionChains(browser)
for _ in range(number_of_executions):
action.double_click(element).send_keys(Keys.BACKSPACE).perform()
将其封装成 清除并输入内容 函数
def double_click_clean(element, browser, number_of_executions=1):
"""
双击内容原理清除输入框中的内容
:param element: 需要操作的元素
:param browser: 浏览器对象
:param number_of_executions: 执行次数,多次执行能有效避免未选全情况
"""
action = ActionChains(browser)
for _ in range(number_of_executions):
action.double_click(element).send_keys(Keys.BACKSPACE).perform()
def clean_with_send(element, browser, text: str, **kwargs):
"""
清空输入框并且输入内容
:param element: 需要操作的元素
:param browser: 浏览器对象
:param text: 输入的内容
"""
double_click_clean(element, browser, **kwargs)
element.send_keys(text)
六、全选后替换「推荐」
众所周知全选的快捷键是Ctrl + A
,通过键盘输入全选快捷键,将输入框中的旧内容全部选中后直接输入替换,实现起来简单且又可靠,也不需要用到专门的动作链接口ActionChains
思路:
先对元素使用send_keys
方法输入Ctrl + A
快捷键后,直接再使用send_keys
方法输入我们想要的内容将其替换即可
def select_all_clean(element):
"""
全选内容原理清除输入框中的内容
:param element: 需要操作的元素
"""
# 发送全选快捷键
element.send_keys(Keys.CONTROL, "a")
element.send_keys(Keys.BACKSPACE)
def clean_with_send(element, text: str):
"""
清空输入框并且输入内容
:param element: 需要操作的元素
:param text: 输入的内容
"""
select_all_clean(element)
element.send_keys(text)
可以将其合并组合成一个函数,只需要短短两行即可实现
def clean_with_send(element, text: str):
"""
清空输入框并且输入内容
:param element: 需要操作的元素
:param text: 输入的内容
"""
# 发送全选快捷键
element.send_keys(Keys.CONTROL, "a")
element.send_keys(text)
七、自带清空元素的内容方法「推荐」
看完上面各种模拟行为清空输入框内容的方法,你一定会想难道Selenium就没有自带清空的方法吗,答案是肯定的,用起来也比较简单,webelement.clear()
方法多用于输入框
想要注意的是,对于某些网页,此方法可以会失效,所以还是得用上面所讲的方法去实现
思路:
没什么特别的,就是清空再输入
def clean_with_send(element, text: str):
"""
清空输入框并且输入内容
:param element: 需要操作的元素
:param text: 输入的内容
"""
element.clear()
element.send_keys(text)
八、总结
其实利用 Selenium.WebDriverWait 对页面进行模拟操作时,无非也是在模仿我们平时上网时的行为罢了,想要对页面进行模拟操作且没思路时,不妨想想要是自己会怎么去操作网页
参考资料💟
- 书籍:
- 异步图书 《Selenium 自动化测试完全指南 基于Python》
这是一本2021年5月新出的书,各方面写的很全,对于学习爬虫或则自动化测试的同学一定不要错过
- 异步图书 《Selenium 自动化测试完全指南 基于Python》
- 官方手册
由衷感谢💖