python+selenium 鼠标操作、键盘操作、.下拉框操作、js处理
1鼠标操作
selenium的ActionChains类提供了一系列模拟鼠标操作的方法,主要操作流程:1、存储鼠标操作;2、调用perform()
执行鼠标操作,支持的操作部分列举如下:
- 🍇
double_click(ele)
:双击 - 🍑
context_click(ele)
:右键 - 🍊
drag_and_drop(source, target)
:从某个元素拖拽到某个元素然后松开 - 🍇
drag_and_drop_by_offset(source, xoffset, yoffset)
:拖拽元素到某个坐标然后松开 - 🍓
move_to_element(ele)
:鼠标悬停在某个元素
下面以百度首页的搜索设置为例,鼠标悬停在【设置】,然后点击显示出来的【搜索设置】:
import time from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By # 启动Chromedriver,并与Chromedriver开启会话 driver = webdriver.Chrome() driver.maximize_window() driver.get("http://www.baidu.com") # 第一步:实例化ActionChains ac = ActionChains(driver) # 第二步:定位要操作的元素 ele = driver.find_element_by_xpath('//span[@id="s-usersetting-top"]') # 第三步:执行对应的操作 ac.move_to_element(ele) # 悬浮操作 # 第四步,释放鼠标动作 ac.perform() # 点击悬停出来的页面上的元素 wait = WebDriverWait(driver, 10) loc = (By.XPATH, '//a[@class="setpref"]') wait.until(EC.visibility_of_element_located(loc)) driver.find_element(*loc).click() time.sleep(2) driver.quit()
这里科普一个知识点,就是链式调用:它可以在一个方法后面接着调用另外的方法,只要它的方法都是返回对象本身即可,如上述的actionchains 用法可以这样写: ActionChains(driver).move_to_element(ele).perform()
。
小知识:查看源码,按住键盘ctrl键,然后鼠标点击一下函数就会跳转到源码。
用一个简单例子来演示一下ActionChains工作流程的原理:
def move_to(): print("正在移动") def click(): print('点击') actions = [] actions.append(move_to) actions.append(click) for action in actions: # perform # action = move_to action()
2键盘操作
selenium提供了比较完整的键盘操作,在使用键盘按键方法前需要先导入keys类:from selenium.webdriver.common.keys import Keys
,它定义了非常多的按键操作,具体的可以问度娘。
常见的一些组合键和非组合键如下:
- 🍊
send_keys(Keys.BACK_SPACE)
删除键 - 🍇
send_keys(Keys.SPACE)
空格键 - 🍋
send_keys(Keys.TAB)
制表tab键 - 🍉
send_keys(Keys.ESCAPE)
回退键 - 🍑
send_keys(Keys.ENTER)
回车键 - 🍓
send_keys(Keys.F5)
刷新键 - 🍅
send_keys(Keys.CONTROL,'a')
全选 - 🍏
send_keys(Keys.CONTROL,'c')
复制 - 🍆
send_keys(Keys.CONTROL,'x')
剪切 - 🍎
send_keys(Keys.CONTROL,'v')
粘贴
3下拉框操作
对select/option类型的下拉列表的操作,我们可以通过点击select标签进行选择选项,另外selenium也提供了Select类来处理select/option去选择下拉列表值:
- 🍦 通过下标选择:
select_by_index(index)
index从0开始 - 🍦 通过value属性:
select_by_value(value值)
- 🍦 通过文本内容:
select_by_visible_text(文本内容)
取消选中则是deselect_by...
,下面以举例的html为例,需要先把该代码保存成html文件,后续直接访问这个本地html文件:
演示代码如下:
4|0Js处理日历控件
在web自动化的过程中,我们常常会遇到有日历控件选择日期的场景,大致分为以下两种:
📆 1、可以直接输入日期(可以通过定位元素然后send_keys
输入日期)
📅 2、不能直接输入日期,只能选择(带有:readonly
(只读)属性)
对于不能直接输入日期的控件,只能通过选择实在太麻烦了。因为不能输入,就会考虑去点击其中的年份、月份、太难的数字。由于日历控件面板很小,单个元素也很小,有可能会产生操作失误的问题,并且代码写起来实在太繁琐了。
那既然selenium支持执行js语句,那我们是不是可以利用js来去掉readonly(即只读)属性,然后直接通过send_keys输入时间呢,试一下吧!
以12306网站买票的出发日期为例,如下图它是有只读属性的,直接代码输入是无法输入的:
import time import datetime from selenium import webdriver from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys # 启动Chromedriver,并与Chromedriver开启会话 driver = webdriver.Chrome() # driver.maximize_window() driver.get("https://www.12306.cn/") wait = WebDriverWait(driver, 30) loc = (By.XPATH, '//input[@id="train_date"]') wait.until(EC.visibility_of_element_located(loc)) js = 'document.getElementById("train_date").readOnly=false;' driver.execute_script(js) time.sleep(2) # 清空日历,重新输入日期 driver.find_element(*loc).clear() today = datetime.date.today() tomorrow = today + datetime.timedelta(days=1) driver.find_element_by_id('train_date').send_keys(str(tomorrow)) time.sleep(2) driver.quit()
举一反三,在碰到selenium处理不了的情况时,我们就可以考虑使用js或者其他方法去实现