From 0098a75990226a6ed66925b6c809b95767efcaf2 Mon Sep 17 00:00:00 2001 From: g1879 Date: Mon, 27 Jul 2020 17:13:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=8F=AF=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E5=88=B0=E7=BB=9D=E5=AF=B9=E5=9D=90=E6=A0=87=E6=88=96=E7=9B=B8?= =?UTF-8?q?=E5=AF=B9=E4=BD=8D=E7=BD=AE=EF=BC=8C=E5=B9=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E9=9A=8F=E6=9C=BA=E6=8A=96=E5=8A=A8=E3=80=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E9=80=9F=E5=BA=A6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/driver_element.py | 61 ++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 13 deletions(-) diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py index df061db..2e94a73 100644 --- a/DrissionPage/driver_element.py +++ b/DrissionPage/driver_element.py @@ -240,24 +240,59 @@ class DriverElement(DrissionElement): except: raise - def drag_to(self, ele_or_loc: Union[tuple, WebElement, DrissionElement]) -> bool: + def drag(self, x: int, y: int, speed: int = 40, shake: bool = True) -> bool: + """拖拽当前元素到相对位置 + :param x: x变化值 + :param y: y变化值 + :param speed: 速度 + :param shake: 是否随机抖动 + :return: 是否推拽成功 + """ + x += self.location['x'] + self.size['width'] // 2 + y += self.location['y'] + self.size['height'] // 2 + return self.drag_to((x, y), speed, shake) + + def drag_to(self, + ele_or_loc: Union[tuple, WebElement, DrissionElement], + speed: int = 40, + shake: bool = True) -> bool: """拖拽当前元素,目标为另一个元素或坐标元组 - :param ele_or_loc: 另一个元素或相对当前位置 + :param ele_or_loc: 另一个元素或坐标元组,坐标为元素中点的坐标 + :param speed: 拖动的速度,默认为None即瞬间到达 + :param shake: 是否随机抖动 :return: 是否拖拽成功 """ - from selenium.webdriver import ActionChains - loc1 = self.location - actions = ActionChains(self._driver) - - if isinstance(ele_or_loc, DriverElement): - actions.drag_and_drop(self.inner_ele, ele_or_loc.inner_ele) - elif isinstance(ele_or_loc, WebElement): - actions.drag_and_drop(self.inner_ele, ele_or_loc) + # x, y:目标坐标点 + if isinstance(ele_or_loc, DriverElement) or isinstance(ele_or_loc, WebElement): + target_x = ele_or_loc.location['x'] + ele_or_loc.size['width'] // 2 + target_y = ele_or_loc.location['y'] + ele_or_loc.size['height'] // 2 elif isinstance(ele_or_loc, tuple): - actions.drag_and_drop_by_offset(self.inner_ele, ele_or_loc[0], ele_or_loc[1]) + target_x, target_y = ele_or_loc else: - raise KeyError('Need WebElement object or coordinate information.') - actions.perform() + raise KeyError('Need DriverElement, WebElement object or coordinate information.') + + current_x = self.location['x'] + self.size['width'] // 2 + current_y = self.location['y'] + self.size['height'] // 2 + width = target_x - current_x + height = target_y - current_y + num = 0 if not speed else int(((abs(width) ** 2 + abs(height) ** 2) ** .5) // speed) + points = [(int(current_x + i * (width / num)), int(current_y + i * (height / num))) for i in range(1, num)] + points.append((target_x, target_y)) + + from selenium.webdriver import ActionChains + from random import randint + actions = ActionChains(self.driver) + loc1 = self.location + for x, y in points: + if shake: + x += randint(-3, 4) + y += randint(-3, 4) + dx = x - current_x + dy = y - current_y + actions.drag_and_drop_by_offset(self.inner_ele, dx, dy) + current_x, current_y = x, y + + actions.release().perform() loc2 = self.location if loc1 == loc2: return False