Pre Merge pull request !52 from Wen-Ming21/dev

This commit is contained in:
Wen-Ming21 2024-10-02 07:01:11 +00:00 committed by Gitee
commit 42ec2c9307
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 69 additions and 10 deletions

View File

@ -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
@ -594,7 +595,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
@ -641,8 +662,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':
@ -652,7 +686,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:

View File

@ -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
"""
...

View File

@ -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()