From f2547421ad96837f4ae876eef9cfee62748c6144 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=A9=E9=93=AD?= <3348431908@qq.com> Date: Wed, 25 Sep 2024 11:48:55 +0000 Subject: [PATCH 1/5] =?UTF-8?q?update=20DrissionPage/=5Felements/chromium?= =?UTF-8?q?=5Felement.py.=20=E5=AE=8C=E5=96=84=E8=8E=B7=E5=8F=96xpath?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BF=9D=E8=AF=81?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E7=9A=84xpath=E8=B7=AF=E5=BE=84=E6=98=AF?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E7=9A=84=20=E4=BC=98=E5=8C=96=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=9A=84css=E8=B7=AF=E5=BE=84=EF=BC=8C=E5=8E=BB?= =?UTF-8?q?=E9=99=A4=E5=A4=9A=E4=BD=99=E7=9A=84=E4=BC=AA=E7=B1=BB=E9=80=89?= =?UTF-8?q?=E6=8B=A9=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 温铭 <3348431908@qq.com> --- DrissionPage/_elements/chromium_element.py | 30 +++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 4e9c1dc..f10d0bb 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -640,8 +640,21 @@ class ChromiumElement(DrissionElement): txt1 = 'let tag = el.nodeName.toLowerCase();' txt3 = ''' && sib.nodeName.toLowerCase()==tag''' txt4 = ''' - if(nth>1){path = '/' + tag + '[' + nth + ']' + path;} - else{path = '/' + tag + path;}''' + let sib1 = el, chi = 0; + while (sib1) { + if (sib1.nodeType === Node.ELEMENT_NODE && sib1.nodeName.toLowerCase() === tag) { + chi += 1; + } + sib1 = sib1.nextSibling; + } + if (nth > 1) { + path = '/' + tag + '[' + nth + ']' + path; + } else if (chi > 1) { + path = '/' + tag + '[1]' + path; + } else { + path = '/' + tag + path; + } + ''' txt5 = '''return path;''' elif mode == 'css': @@ -651,7 +664,18 @@ class ChromiumElement(DrissionElement): break;} ''' txt3 = '' - txt4 = '''path = '>' + el.tagName.toLowerCase() + ":nth-child(" + nth + ")" + path;''' + txt4 = '''let tag = el.nodeName.toLowerCase(), sib1 = el, chi = 0; + while (sib1) { + if (sib1.nodeType === Node.ELEMENT_NODE && sib1.nodeName.toLowerCase() === tag) { + chi += 1; + } + sib1 = sib1.nextSibling; + } + if (nth > 1 || chi > 1) { + path = '>' + el.tagName.toLowerCase() + ":nth-child(" + nth + ")" + path; + } else { + path = '>' + el.tagName.toLowerCase() + path; + }''' txt5 = '''return path.substr(1);''' else: From cde7fc7b8d5e9cd7f8918b506e56af53489ce9a7 Mon Sep 17 00:00:00 2001 From: Wen-Ming21 <3348431908@qq.com> Date: Wed, 25 Sep 2024 14:42:21 +0000 Subject: [PATCH 2/5] update DrissionPage/_elements/session_element.py. Signed-off-by: Wen-Ming21 <3348431908@qq.com> --- DrissionPage/_elements/session_element.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/DrissionPage/_elements/session_element.py b/DrissionPage/_elements/session_element.py index d0cba7a..4a9aa86 100644 --- a/DrissionPage/_elements/session_element.py +++ b/DrissionPage/_elements/session_element.py @@ -155,11 +155,14 @@ class SessionElement(DrissionElement): if id_: path_str = f'>{ele.tag}#{id_}{path_str}' break - brothers = len(ele.eles(f'xpath:./preceding-sibling::*')) - path_str = f'>{ele.tag}:nth-child({brothers + 1}){path_str}' + before_brothers = len(ele.eles(f'xpath:./preceding-sibling::*')) + after_brothers = len(ele.eles(f'xpath:./following-sibling::*')) + path_str = f'>{ele.tag}:nth-child({before_brothers + 1}){path_str}' if ( + before_brothers or after_brothers) else f'>{ele.tag}{path_str}' else: - brothers = len(ele.eles(f'xpath:./preceding-sibling::{ele.tag}')) - path_str = f'/{ele.tag}[{brothers + 1}]{path_str}' if brothers > 0 else f'/{ele.tag}{path_str}' + before_brothers = len(ele.eles(f'xpath:./preceding-sibling::{ele.tag}')) + after_brothers = len(ele.eles(f'xpath:./following-sibling::{ele.tag}')) + path_str = f'/{ele.tag}[{before_brothers + 1}]{path_str}' if before_brothers > 0 else f'/{ele.tag}[1]{path_str}' if after_brothers > 0 else f'/{ele.tag}{path_str}' ele = ele.parent() From 1bb32ba6179fd6d1b508db51e93fbcf161ca8448 Mon Sep 17 00:00:00 2001 From: Wen-Ming21 <3348431908@qq.com> Date: Wed, 2 Oct 2024 06:54:45 +0000 Subject: [PATCH 3/5] =?UTF-8?q?update=20DrissionPage/=5Felements/chromium?= =?UTF-8?q?=5Felement.py.=20=E6=96=B0=E5=A2=9E=E5=BC=BA=E5=88=B6=E4=BF=9D?= =?UTF-8?q?=E6=8C=81=E5=85=83=E7=B4=A0=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Wen-Ming21 <3348431908@qq.com> --- DrissionPage/_elements/chromium_element.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index f10d0bb..90bc03f 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -593,7 +593,27 @@ class ChromiumElement(DrissionElement): self._run_js('this.focus();') return self - def hover(self, offset_x=None, offset_y=None): + def keep_pseudo_state(self, forcedPseudoClasses): + while self.__dict__.get('keep_count', 0): + self.owner.run_cdp('CSS.enable') + self.owner.run_cdp('CSS.forcePseudoState', nodeId=self._node_id, forcedPseudoClasses=forcedPseudoClasses) + + def force_pseudo_state(self, keep_state=True, forcedPseudoClasses=None): + if not forcedPseudoClasses: + forcedPseudoClasses = ['hover'] + if keep_state and self.__dict__.get('keep_count', 0) == 0: + from random import randint + x, y = self.owner.rect.size + x, y = (x, y) if x <= y else (y, x) + self.owner.actions.move_to(self, offset_x=randint(x, y), offset_y=randint(x, y), duration=.1) + self.__dict__['keep_count'] = 1 + Thread(target=self.keep_pseudo_state, args=(forcedPseudoClasses,)).start() + if self.__dict__.get('keep_count', 0) > 0 and not keep_state: + del self.__dict__['keep_count'] + return self + + def hover(self, offset_x=None, offset_y=None, keep_hover=False): + self.force_pseudo_state(keep_hover, forcedPseudoClasses=['hover']) self.owner.actions.move_to(self, offset_x=offset_x, offset_y=offset_y, duration=.1) return self From 5fc8ca2773906d6e1d47db31bbb0e6828e8aecde Mon Sep 17 00:00:00 2001 From: Wen-Ming21 <3348431908@qq.com> Date: Wed, 2 Oct 2024 06:55:32 +0000 Subject: [PATCH 4/5] update DrissionPage/_elements/chromium_element.py. Signed-off-by: Wen-Ming21 <3348431908@qq.com> --- DrissionPage/_elements/chromium_element.py | 1 + 1 file changed, 1 insertion(+) diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 90bc03f..3f152ee 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -9,6 +9,7 @@ from json import loads from os.path import basename from pathlib import Path from re import search +from threading import Thread from time import perf_counter, sleep from DataRecorder.tools import get_usable_path, make_valid_name From 6b7ae3c3ee93fac4708f7402f65332e617d7be82 Mon Sep 17 00:00:00 2001 From: Wen-Ming21 <3348431908@qq.com> Date: Wed, 2 Oct 2024 07:01:10 +0000 Subject: [PATCH 5/5] update DrissionPage/_elements/chromium_element.pyi. Signed-off-by: Wen-Ming21 <3348431908@qq.com> --- DrissionPage/_elements/chromium_element.pyi | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/DrissionPage/_elements/chromium_element.pyi b/DrissionPage/_elements/chromium_element.pyi index 09ab107..225c30f 100644 --- a/DrissionPage/_elements/chromium_element.pyi +++ b/DrissionPage/_elements/chromium_element.pyi @@ -550,10 +550,21 @@ class ChromiumElement(DrissionElement): """使元素获取焦点""" ... - def hover(self, offset_x: int = None, offset_y: int = None) -> ChromiumElement: - """鼠标悬停,可接受偏移量,偏移量相对于元素左上角坐标。不传入offset_x和offset_y值时悬停在元素中点 + def force_pseudo_state(self, keep_state: bool = True, + forcedPseudoClasses: list[str] = ['hover']) -> ChromiumElement: + """ + 强制元素保持状态,如鼠标悬停,keep_state为True时需再次调用取消强制元素保持状态 + :param keep_state: 是否强制元素保持某个状态,默认为True + :param forcedPseudoClasses: 默认为['hover'],可用参数:active,hover,focus,focus-within,focus-visible,target + :return: None + """ + ... + + def hover(self, offset_x: int = None, offset_y: int = None, keep_hover: bool = False) -> ChromiumElement: + """鼠标悬停,可接受偏移量,偏移量相对于元素左上角坐标。不传入offset_x和offset_y值时悬停在元素中点,keep_hover为True时需再次调用取消强制hover :param offset_x: 相对元素左上角坐标的x轴偏移量 :param offset_y: 相对元素左上角坐标的y轴偏移量 + :param keep_hover: 为True时保持元素hover时的样式,为False时取消强制hover :return: None """ ...