selenium模拟鼠标操作

摘要:
Selenium提供了一个类ActionChains来处理模拟的鼠标事件,例如单击、双击、拖动等。

Selenium提供了一个类ActionChains来处理模拟鼠标事件,如单击、双击、拖动等。

基本语法:

class ActionChains(object):
    """
    ActionChains are a way to automate low level interactions such as
    mouse movements, mouse button actions, key press, and context menu interactions.
    This is useful for doing more complex actions like hover over and drag and drop.

    Generate user actions.
       When you call methods for actions on the ActionChains object,
       the actions are stored in a queue in the ActionChains object.
       When you call perform(), the events are fired in the order they
       are queued up.

    ActionChains can be used in a chain pattern::

        menu = driver.find_element_by_css_selector(".nav")
        hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

        ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()

    Or actions can be queued up one by one, then performed.::

        menu = driver.find_element_by_css_selector(".nav")
        hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

        actions = ActionChains(driver)
        actions.move_to_element(menu)
        actions.click(hidden_submenu)
        actions.perform()

    Either way, the actions are performed in the order they are called, one after
    another.
    """

    def __init__(self, driver):
        """
        Creates a new ActionChains.

        :Args:
         - driver: The WebDriver instance which performs user actions.
        """
        self._driver = driver
        self._actions = []
        if self._driver.w3c:
            self.w3c_actions = ActionBuilder(driver)

    def perform(self):
        """
        Performs all stored actions.
        """
        if self._driver.w3c:
            self.w3c_actions.perform()
        else:
            for action in self._actions:
                action()

    def reset_actions(self):
        """
            Clears actions that are already stored on the remote end.
        """
        if self._driver.w3c:
            self._driver.execute(Command.W3C_CLEAR_ACTIONS)
        else:
            self._actions = []

    def click(self, on_element=None):
        """
        Clicks an element.

        :Args:
         - on_element: The element to click.
           If None, clicks on current mouse position.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.click(on_element)
            self.w3c_actions.key_action.pause()
            self.w3c_actions.key_action.pause()
        else:
            if on_element:
                self.move_to_element(on_element)
            self._actions.append(lambda: self._driver.execute(
                                 Command.CLICK, {'button': 0}))
        return self

    def click_and_hold(self, on_element=None):
        """
        Holds down the left mouse button on an element.

        :Args:
         - on_element: The element to mouse down.
           If None, clicks on current mouse position.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.click_and_hold(on_element)
            self.w3c_actions.key_action.pause()
            if on_element:
                self.w3c_actions.key_action.pause()
        else:
            if on_element:
                self.move_to_element(on_element)
            self._actions.append(lambda: self._driver.execute(
                                 Command.MOUSE_DOWN, {}))
        return self

    def context_click(self, on_element=None):
        """
        Performs a context-click (right click) on an element.

        :Args:
         - on_element: The element to context-click.
           If None, clicks on current mouse position.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.context_click(on_element)
            self.w3c_actions.key_action.pause()
        else:
            if on_element:
                self.move_to_element(on_element)
            self._actions.append(lambda: self._driver.execute(
                                 Command.CLICK, {'button': 2}))
        return self

    def double_click(self, on_element=None):
        """
        Double-clicks an element.

        :Args:
         - on_element: The element to double-click.
           If None, clicks on current mouse position.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.double_click(on_element)
            for _ in range(4):
                self.w3c_actions.key_action.pause()
        else:
            if on_element:
                self.move_to_element(on_element)
            self._actions.append(lambda: self._driver.execute(
                                 Command.DOUBLE_CLICK, {}))
        return self

    def drag_and_drop(self, source, target):
        """
        Holds down the left mouse button on the source element,
           then moves to the target element and releases the mouse button.

        :Args:
         - source: The element to mouse down.
         - target: The element to mouse up.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.click_and_hold(source) 
                                           .move_to(target) 
                                           .release()
            for _ in range(3):
                self.w3c_actions.key_action.pause()
        else:
            self.click_and_hold(source)
            self.release(target)
        return self

    def drag_and_drop_by_offset(self, source, xoffset, yoffset):
        """
        Holds down the left mouse button on the source element,
           then moves to the target offset and releases the mouse button.

        :Args:
         - source: The element to mouse down.
         - xoffset: X offset to move to.
         - yoffset: Y offset to move to.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.click_and_hold(source) 
                                           .move_to_location(xoffset, yoffset) 
                                           .release()
            for _ in range(3):
                self.w3c_actions.key_action.pause()
        else:
            self.click_and_hold(source)
            self.move_by_offset(xoffset, yoffset)
            self.release()
        return self

    def key_down(self, value, element=None):
        """
        Sends a key press only, without releasing it.
           Should only be used with modifier keys (Control, Alt and Shift).

        :Args:
         - value: The modifier key to send. Values are defined in `Keys` class.
         - element: The element to send keys.
           If None, sends a key to current focused element.

        Example, pressing ctrl+c::

            ActionChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

        """
        if element:
            self.click(element)
        if self._driver.w3c:
            self.w3c_actions.key_action.key_down(value)
            self.w3c_actions.pointer_action.pause()
        else:
            self._actions.append(lambda: self._driver.execute(
                Command.SEND_KEYS_TO_ACTIVE_ELEMENT,
                {"value": keys_to_typing(value)}))
        return self

    def key_up(self, value, element=None):
        """
        Releases a modifier key.

        :Args:
         - value: The modifier key to send. Values are defined in Keys class.
         - element: The element to send keys.
           If None, sends a key to current focused element.

        Example, pressing ctrl+c::

            ActionChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

        """
        if element:
            self.click(element)
        if self._driver.w3c:
            self.w3c_actions.key_action.key_up(value)
            self.w3c_actions.pointer_action.pause()
        else:
            self._actions.append(lambda: self._driver.execute(
                Command.SEND_KEYS_TO_ACTIVE_ELEMENT,
                {"value": keys_to_typing(value)}))
        return self

    def move_by_offset(self, xoffset, yoffset):
        """
        Moving the mouse to an offset from current mouse position.

        :Args:
         - xoffset: X offset to move to, as a positive or negative integer.
         - yoffset: Y offset to move to, as a positive or negative integer.
        """
        self._actions.append(lambda: self._driver.execute(
            Command.MOVE_TO, {
                'xoffset': int(xoffset),
                'yoffset': int(yoffset)}))
        return self

    def move_to_element(self, to_element):
        """
        Moving the mouse to the middle of an element.

        :Args:
         - to_element: The WebElement to move to.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.move_to(to_element)
            self.w3c_actions.key_action.pause()
        else:
            self._actions.append(lambda: self._driver.execute(
                                 Command.MOVE_TO, {'element': to_element.id}))
        return self

    def move_to_element_with_offset(self, to_element, xoffset, yoffset):
        """
        Move the mouse by an offset of the specified element.
           Offsets are relative to the top-left corner of the element.

        :Args:
         - to_element: The WebElement to move to.
         - xoffset: X offset to move to.
         - yoffset: Y offset to move to.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.move_to(to_element, xoffset, yoffset)
            self.w3c_actions.key_action.pause()
        else:
            self._actions.append(
                lambda: self._driver.execute(Command.MOVE_TO, {
                    'element': to_element.id,
                    'xoffset': int(xoffset),
                    'yoffset': int(yoffset)}))
        return self

    def release(self, on_element=None):
        """
        Releasing a held mouse button on an element.

        :Args:
         - on_element: The element to mouse up.
           If None, releases on current mouse position.
        """
        if self._driver.w3c:
            self.w3c_actions.pointer_action.release()
            self.w3c_actions.key_action.pause()
        else:
            if on_element:
                self.move_to_element(on_element)
            self._actions.append(lambda: self._driver.execute(Command.MOUSE_UP, {}))
        return self

    def send_keys(self, *keys_to_send):
        """
        Sends keys to current focused element.

        :Args:
         - keys_to_send: The keys to send.  Modifier keys constants can be found in the
           'Keys' class.
        """
        if self._driver.w3c:
            self.w3c_actions.key_action.send_keys(keys_to_send)
        else:
            self._actions.append(lambda: self._driver.execute(
                Command.SEND_KEYS_TO_ACTIVE_ELEMENT, {'value': keys_to_typing(keys_to_send)}))
        return self

    def send_keys_to_element(self, element, *keys_to_send):
        """
        Sends keys to an element.

        :Args:
         - element: The element to send keys.
         - keys_to_send: The keys to send.  Modifier keys constants can be found in the
           'Keys' class.
        """
        if self._driver.w3c:
            self.w3c_actions.key_action.send_keys(keys_to_send, element=element)
        else:
            self._actions.append(lambda: element.send_keys(*keys_to_send))
        return self

    # Context manager so ActionChains can be used in a 'with .. as' statements.
    def __enter__(self):
        return self  # Return created instance of self.

    def __exit__(self, _type, _value, _traceback):
        pass  # Do nothing, does not require additional cleanup.

  方法列表

perform(self):        ---执行链中的所有动作
reset_actions(self):     ---清除存储在远端的动作
click(self, on_element=None):   ---鼠标左键单击
click_and_hold(self, on_element=None):    --鼠标左键单击,不松开
context_click(self, on_element=None):		---鼠标右键单击
double_click(self, on_element=None):		---鼠标左键双击
drag_and_drop(self, source, target):		---拖拽到某个元素后松开
drag_and_drop_by_offset(self, source, xoffset, yoffset):		---拖拽到某个坐标后松开
key_down(self, value, element=None):		---某个键盘键被按下
key_up(self, value, element=None):			---松开某个键
move_by_offset(self, xoffset, yoffset):		---鼠标移动到某个坐标
move_to_element(self, to_element):			---鼠标移动到某个元素
move_to_element_with_offset(self, to_element, xoffset, yoffset):		---移动到距某个元素(左上角)多少的位置
release(self, on_element=None):		---在某元素上松开鼠标
send_keys(self, *keys_to_send):		---发送某些值到当前焦点元素
send_keys_to_element(self, element, *keys_to_send):		---发送某些值到指定元素

基本用法

链式写法
ActionChains(driver).click(clk_btn).context_click(right_btn).perform()

分步写法
# 补全化action
actions = ActionChains(driver)
# 装载单击动作
actions.click()
# 装载右击动作
actions.context_click()
# 执行所有被装载的动作
actions.perform()

应用举例

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

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

driver = webdriver.Chrome()
driver.get("https://www.baidu.com/")
driver.implicitly_wait(10)

# 右击百度新闻
right_click = driver.find_element_by_xpath('//a[@name="tj_trnews"]')
ActionChains(driver).context_click(right_click).perform()

selenium模拟鼠标操作第1张

参考 文档:

 http://www.jb51.net/article/92682.htm

下拉滚动条

  方法一:

使用js脚本直接操作

js="var q=document.documentElement.scrollTop=10000"
driver.execute_script(js)

  方法二、

将滚动条手动到指定的位置,这种方法更常用 

target = driver.find_element_by_id("id_keypair")
driver.execute_script("arguments[0].scrollIntoView();", target) #拖动到可见的元素去

  方法三、

发送TAB键

from selenium.webdriver.common.keys import Keys
driver.find_element_by_id("id_login_method_0").send_keys(Keys.TAB)

  方法四、

前段时间使用robotframe work框架时,selenium2library里面有一个非常好用的功能Focus,会自动定位到元素,研读一下源码:

def focus(self, locator):
        """Sets focus to element identified by `locator`."""
        element = self._element_find(locator, True, True)
        self._current_browser().execute_script("arguments[0].focus();", element)

  从源码中我们可以看到,此方法与我们在python自己写的方法二)一致,工具给我们做了封装。

免责声明:文章转载自《selenium模拟鼠标操作》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇转:intent简介开放源代码的全文检索引擎Lucene下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

swipe.js 轻松实现手机端滑动效果

插件下载地址 官网:http://www.swipejs.comgithub:https://github.com/bradbirdsall/Swipe 插件特色 swipe.js是一个比较有名的触摸滑动插件,它能够处理内容滑动,支持自定义选项,你可以让它自动滚动,控制滚动间隔,返回回调函数等。经常可见使用在移动开发中 使用方法 HTML代码如下: <...

element ui Cascader 级联选择器 关闭tag时报错 :vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in callback for watcher "value": "TypeError: Cannot read property 'level' of null"

情况说明:多选后,点击关闭tag的按钮,会出现如下报错。   经过使用官网列子,及数据。发现删除tag并不会出现这个错误。经过对比,唯一不同的是官网的value 是字符串对象,而我使用的id是数字。将id改成字符串格式后,问题就解决了。 ☀ ░ 标记一下░  ☀...

使用Python操作Redis详解

之前的五天,过了个愉快的周末,然后将公司AbaseDump的调度部分代码看懂并且在此之上完成了OnlyDump的功能代码,代码不可以公开,今天完工,明天测试,晚上来总结一下这几天学到的一点应用。 使用Python操作Redis详解 ---------------------------------------------------------------...

selenium定位多个嵌套iframe

一. driver.switch_to.frame(id):可以通过id切换到iframe之前学习了selenium切换到iframe的方法,代码如下 from selenium import webdriver driver = webdriver.Chrome() driver.switch_to.frame(0)...

Selenium Webdirver API(1)

Selenium Webdirver API 前提:引入webdriver包 from selenium import webdriver 1、创建浏览器对象driver = webdriver.Ie(executable_path="D:\IEDriverServer")#不同浏览器只需更改浏览器名称即可,如:webdriver.Chrome() web...

第七部分(一) 动态渲染页面爬取(Selenium的使用)

Ajax分析和抓取方式,是JavaScript动态渲染页面的一种情形,可使用 requests 或 urllib 爬取数据。JavaScript动态渲染的页面不是只有Ajax一种,比如中国青年网 http://news.youth.cn/gn/ 的分页部分由JavaScript生成的,不是原始的HTML代码,但是不包含Ajax请求。又比如ECharts的...