上一个教程简单的进行了selenium的入门(python之selenium入门教程),这里主要学习元素的复杂操作,比如键盘输入、鼠标点击、滚动等。
selenium的ActionChains封装了一系列模拟页面的复杂的操作,比如双击、右键、拖拽等。
调用ActionChains的方法时,相关指定操作不会立即执行,而是将操作按顺序放在一个队列里,只有当调用了perform()方法时,才会根据队列中的事件依次执行。
ActionChains使用的基本步骤如下:
action = ActionChains(driver)
action.方法1.方法2.方法3.方法n
action.方法1
action.方法2
...
action.方法n
action.perform()
点击包含了鼠标左键单击、双击,和右键单击,常用的点击就这3个
click(on_element=None)
:单击元素on_elementdouble_click(on_element=None)
:双击指定的元素on_elementcontext_click(on_element=None)
:右键点击指定的元素on_element现在以央视的微视频来进行练习:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
if __name__ == "__main__":
# 定义一个WebDriver对象
driver = webdriver.Chrome()
driver.implicitly_wait(30)
# 打开央视微视频首页
driver.get("https://tv.cctv.com/wsp/m/index.shtml")
action = ActionChains(driver)
# 单击第一个视频,播放视频
action.click(driver.find_element(By.ID, "flash_video0_player_html5_api")).pause(4)
# 双击视频,放大播放器
action.double_click(driver.find_element(By.ID, "flash_video0_player_html5_api")).pause(5)
# 右键点击播放器,显示目录
action.context_click(driver.find_element(By.ID, "flash_video0_player_html5_api")).pause(2)
action.perform()
# 终止相关进程
driver.quit()
有时候我们需要将鼠标悬停到某个位置后才显示完整的内容,鼠标悬停可以理解为将鼠标移动到某个位置:
move_to_element(to_element)
:将鼠标移动到指定的元素位置to_element比如打开百度首页,将鼠标悬停到顶部导航栏的“更多”位置处
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
if __name__ == "__main__":
# 定义一个WebDriver对象
driver = webdriver.Chrome()
driver.implicitly_wait(30)
# 打开百度首页
driver.get("https://www.baidu.com/")
action = ActionChains(driver)
# 将鼠标移动到“更多”元素位置上
action.move_to_element(driver.find_element(By.LINK_TEXT, "更多")).pause(3)
action.perform()
# 终止相关进程
driver.quit()
有时候我们需要将某个元素移动到另一个位置,即拖拽。
drag_and_drop(source, target)
:将元素source移动到元素target的位置(类似于中心点对接,即2者的中心点在同一个位置)drag_and_drop_by_offset(source, xoffset, yoffset)
:将元素source移动到指定的偏移位置from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
if __name__ == "__main__":
# 定义一个WebDriver对象
driver = webdriver.Chrome()
driver.implicitly_wait(15)
# 打开知乎首页
driver.get("https://www.zhihu.com/")
action = ActionChains(driver)
# 在手机号输入框中输入手机号
action.send_keys_to_element(driver.find_element(By.XPATH, "//input[@type='tel']"), "18819445561").pause(1)
# 点击“获取短信验证码”
action.click(driver.find_element(By.XPATH, "//button[text()='获取短信验证码']")).pause(1)
# 执行前2步骤后,就会打开安全验证弹窗
action.perform()
# 在打开了安全验证弹窗后,定位需要移动的元素和移动后的目标位置
source = driver.find_element(By.XPATH, "//div[@class='yidun_control']//div[@class='yidun_slider']")
target = driver.find_element(By.XPATH, "//div[@class='yidun_control']//span[contains(text(), '向右拖动滑块填充拼图')]")
# 使用drag_and_drop()移动source元素到target元素位置
action.drag_and_drop(source, target).pause(3)
# 使用drag_and_drop_by_offset()移动source元素到偏移距离
action.drag_and_drop_by_offset(source, 100, 0).pause(2)
action.perform()
# 终止相关进程
driver.quit()
执行结果如下:
有时候页面展示内容过多,浏览器不能显示完成的内容,就有了滚动条,我们可以根据元素坐标去滚动页面。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
if __name__ == "__main__":
# 定义一个WebDriver对象
driver = webdriver.Chrome()
driver.implicitly_wait(30)
# 打开央视微视频首页
driver.get("https://www.baidu.com/s?wd=中国春节")
action = ActionChains(driver)
# 百度热搜 词条的定位
hot_search = driver.find_element(By.XPATH, "//div[@class='FYB_RD']//div[@title='百度热搜']")
# 相关热搜 元素的定位
related_search = driver.find_element(By.XPATH, "//div[@id='rs_new']/div")
# 根据scroll_by_amount()确认滚动的位置,横坐标偏移为0,表示不横向滚动,纵坐标为元素的y坐标,表示滚动到 相关热搜 处
action.scroll_by_amount(0, int(related_search.rect["y"])).pause(2)
# 滚动到 百度热搜 处
action.scroll_to_element(hot_search).pause(2)
action.perform()
# 终止相关进程
driver.quit()
执行结果如下:
如果页面是静态页面的话,可以滚动到指定的元素附近,如果页面的元素随着滚动有变化(比如属性、CSS等),则不建议直接定位到最终的元素位置,需要一点一点的滚动,尽量在页面的展示内容附近去慢慢滚动,多次滚动到最终位置。
ActionChains支持模拟键盘按键,比如按键、长按等操作
常规按键是指我们经常敲字的时候的按键,即单击。
模拟常规按键的方法有2个:send_keys_to_element(element, *keys_to_send)
和send_keys(*keys_to_send)
send_keys()必须是在有光标的地方输入内容,没有光标的话会输入错误,send_keys_to_element()是往指定元素element中输入内容,该方法实际上是find_element之后,将查找到的元素进行click(),然后调用了send_keys(),send_keys()又是根据key_down()和key_up()方法来实现的。
示例:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
if __name__ == "__main__":
# 定义一个WebDriver对象
driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
action = ActionChains(driver)
search = driver.find_element(By.ID, "kw")
# 模拟按键往搜索框中输入
action.send_keys_to_element(search, "狐妖小红娘 2").pause(1)
# 搜索框,输入删除键(类似于按键Backspace)
action.send_keys_to_element(search, Keys.BACK_SPACE).pause(1)
# 搜索框中追加输入内容
action.send_keys_to_element(search, "第二季").pause(1)
# 搜索框中输入Enter键,下拉框消失
action.send_keys(Keys.ENTER).pause(2)
# 执行搜索框的输入操作
action.perform()
# 终止相关进程
driver.quit()
执行结果如下:
除了我们日常可以字符串表示的字母和数字,其他较常用的按键被设置成了常量,在selenium.webdriver.common.keys.Keys
中定义。
有时候我们要使用快捷键,就需要长按某个键,比如Ctrl+C复制文本内容等。我们可以使用ActionChains的key_down(value, element=None)
和key_up(value, element=None)
方法,key_down()表示按下,key_up()表示放开(即按键上升)
比如Ctrl+A全选页面,实现如下:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
if __name__ == "__main__":
# 定义一个WebDriver对象
driver = webdriver.Chrome()
# 打开csdn首页
driver.get("https://www.csdn.net/")
action = ActionChains(driver)
# 使用Ctrl+a全选页面,页面文本内容会变成蓝色
action.key_down(Keys.CONTROL).send_keys("a").key_up(Keys.CONTROL)
# 暂停2秒
action.pause(2).perform()
# 终止相关进程
driver.quit()
官方文档:WebDriver API
指导文档:Actions API