mirror of
https://gitee.com/g1879/DrissionPage.git
synced 2024-12-10 04:00:23 +08:00
增加匹配开头和结尾语法;页面对象增加窗口状态属性;设置平滑滚动时自动切换是否等待;ChromiumPage设置cookies时自动添加域名
This commit is contained in:
parent
04e82ee5e6
commit
ac52c699a5
@ -8,6 +8,7 @@ from json import loads, JSONDecodeError
|
|||||||
from os import sep
|
from os import sep
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from time import perf_counter, sleep, time
|
from time import perf_counter, sleep, time
|
||||||
|
from urllib.parse import urlparse
|
||||||
from warnings import warn
|
from warnings import warn
|
||||||
|
|
||||||
from requests import Session
|
from requests import Session
|
||||||
@ -990,11 +991,10 @@ class ChromiumBaseSetter(object):
|
|||||||
result_cookies = []
|
result_cookies = []
|
||||||
for cookie in cookies:
|
for cookie in cookies:
|
||||||
if not cookie.get('domain', None):
|
if not cookie.get('domain', None):
|
||||||
continue
|
cookie['domain'] = urlparse(self._page.url).netloc
|
||||||
c = {'value': '' if cookie['value'] is None else cookie['value'],
|
result_cookies.append({'value': '' if cookie['value'] is None else cookie['value'],
|
||||||
'name': cookie['name'],
|
'name': cookie['name'],
|
||||||
'domain': cookie['domain']}
|
'domain': cookie['domain']})
|
||||||
result_cookies.append(c)
|
|
||||||
self._page.run_cdp_loaded('Network.setCookies', cookies=result_cookies)
|
self._page.run_cdp_loaded('Network.setCookies', cookies=result_cookies)
|
||||||
|
|
||||||
def upload_files(self, files):
|
def upload_files(self, files):
|
||||||
@ -1192,3 +1192,4 @@ class PageScrollSetter(object):
|
|||||||
raise TypeError('on_off必须为bool。')
|
raise TypeError('on_off必须为bool。')
|
||||||
b = 'smooth' if on_off else 'auto'
|
b = 'smooth' if on_off else 'auto'
|
||||||
self._scroll._driver.run_js(f'document.documentElement.style.setProperty("scroll-behavior","{b}");')
|
self._scroll._driver.run_js(f'document.documentElement.style.setProperty("scroll-behavior","{b}");')
|
||||||
|
self._scroll._wait_complete = on_off
|
||||||
|
@ -402,6 +402,11 @@ class ChromiumTabRect(object):
|
|||||||
def __init__(self, page):
|
def __init__(self, page):
|
||||||
self._page = page
|
self._page = page
|
||||||
|
|
||||||
|
@property
|
||||||
|
def window_state(self):
|
||||||
|
"""返回窗口状态:normal、fullscreen、maximized、 minimized"""
|
||||||
|
return self._get_browser_rect()['windowState']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def browser_location(self):
|
def browser_location(self):
|
||||||
"""返回浏览器在屏幕上的坐标,左上角为(0, 0)"""
|
"""返回浏览器在屏幕上的坐标,左上角为(0, 0)"""
|
||||||
|
@ -116,6 +116,9 @@ class ChromiumTabRect(object):
|
|||||||
def __init__(self, page: ChromiumPage):
|
def __init__(self, page: ChromiumPage):
|
||||||
self._page: ChromiumPage = ...
|
self._page: ChromiumPage = ...
|
||||||
|
|
||||||
|
@property
|
||||||
|
def window_state(self) -> str: ...
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def browser_location(self) -> Tuple[int, int]: ...
|
def browser_location(self) -> Tuple[int, int]: ...
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ def set_prefs(opt):
|
|||||||
prefs = opt.preferences
|
prefs = opt.preferences
|
||||||
del_list = opt._prefs_to_del
|
del_list = opt._prefs_to_del
|
||||||
else:
|
else:
|
||||||
prefs = opt.experimental_options.get('prefs', None)
|
prefs = opt.experimental_options.get('prefs', [])
|
||||||
del_list = []
|
del_list = []
|
||||||
|
|
||||||
if not opt.user_data_path:
|
if not opt.user_data_path:
|
||||||
|
@ -36,19 +36,19 @@ def get_loc(loc, translate_css=False):
|
|||||||
|
|
||||||
def str_to_loc(loc):
|
def str_to_loc(loc):
|
||||||
"""处理元素查找语句
|
"""处理元素查找语句
|
||||||
查找方式:属性、tag name及属性、文本、xpath、css selector、id、class
|
:param loc: 查找语法字符串
|
||||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串
|
:return: 匹配符元组
|
||||||
"""
|
"""
|
||||||
loc_by = 'xpath'
|
loc_by = 'xpath'
|
||||||
|
|
||||||
if loc.startswith('.'):
|
if loc.startswith('.'):
|
||||||
if loc.startswith(('.=', '.:',)):
|
if loc.startswith(('.=', '.:', '.^', '.$')):
|
||||||
loc = loc.replace('.', '@class', 1)
|
loc = loc.replace('.', '@class', 1)
|
||||||
else:
|
else:
|
||||||
loc = loc.replace('.', '@class=', 1)
|
loc = loc.replace('.', '@class=', 1)
|
||||||
|
|
||||||
elif loc.startswith('#'):
|
elif loc.startswith('#'):
|
||||||
if loc.startswith(('#=', '#:',)):
|
if loc.startswith(('#=', '#:', '#^', '#$')):
|
||||||
loc = loc.replace('#', '@id', 1)
|
loc = loc.replace('#', '@id', 1)
|
||||||
else:
|
else:
|
||||||
loc = loc.replace('#', '@id=', 1)
|
loc = loc.replace('#', '@id=', 1)
|
||||||
@ -56,7 +56,7 @@ def str_to_loc(loc):
|
|||||||
elif loc.startswith(('t:', 't=')):
|
elif loc.startswith(('t:', 't=')):
|
||||||
loc = f'tag:{loc[2:]}'
|
loc = f'tag:{loc[2:]}'
|
||||||
|
|
||||||
elif loc.startswith(('tx:', 'tx=')):
|
elif loc.startswith(('tx:', 'tx=', 'tx^', 'tx$')):
|
||||||
loc = f'text{loc[2:]}'
|
loc = f'text{loc[2:]}'
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
@ -87,9 +87,17 @@ def str_to_loc(loc):
|
|||||||
# 根据文本查找
|
# 根据文本查找
|
||||||
elif loc.startswith('text='):
|
elif loc.startswith('text='):
|
||||||
loc_str = f'//*[text()={_make_search_str(loc[5:])}]'
|
loc_str = f'//*[text()={_make_search_str(loc[5:])}]'
|
||||||
|
|
||||||
elif loc.startswith('text:') and loc != 'text:':
|
elif loc.startswith('text:') and loc != 'text:':
|
||||||
loc_str = f'//*/text()[contains(., {_make_search_str(loc[5:])})]/..'
|
loc_str = f'//*/text()[contains(., {_make_search_str(loc[5:])})]/..'
|
||||||
|
|
||||||
|
elif loc.startswith('text^') and loc != 'text^':
|
||||||
|
loc_str = f'//*/text()[starts-with(., {_make_search_str(loc[5:])})]/..'
|
||||||
|
|
||||||
|
elif loc.startswith('text$') and loc != 'text$':
|
||||||
|
loc_str = f'//*/text()[substring(., string-length(.) - string-length({_make_search_str(loc[5:])}) +1) = ' \
|
||||||
|
f'{_make_search_str(loc[5:])}]/..'
|
||||||
|
|
||||||
# 用xpath查找
|
# 用xpath查找
|
||||||
elif loc.startswith(('xpath:', 'xpath=')) and loc not in ('xpath:', 'xpath='):
|
elif loc.startswith(('xpath:', 'xpath=')) and loc not in ('xpath:', 'xpath='):
|
||||||
loc_str = loc[6:]
|
loc_str = loc[6:]
|
||||||
@ -100,7 +108,7 @@ def str_to_loc(loc):
|
|||||||
elif loc.startswith(('css:', 'css=')) and loc not in ('css:', 'css='):
|
elif loc.startswith(('css:', 'css=')) and loc not in ('css:', 'css='):
|
||||||
loc_by = 'css selector'
|
loc_by = 'css selector'
|
||||||
loc_str = loc[4:]
|
loc_str = loc[4:]
|
||||||
elif loc.startswith(('c:', 'c=')) and loc not in ('c:', 'c='):
|
elif loc.startswith(('c:', 'cx=')) and loc not in ('c:', 'cx='):
|
||||||
loc_by = 'css selector'
|
loc_by = 'css selector'
|
||||||
loc_str = loc[2:]
|
loc_str = loc[2:]
|
||||||
|
|
||||||
@ -126,24 +134,44 @@ def _make_single_xpath_str(tag: str, text: str) -> str:
|
|||||||
arg_str = 'not(@*)'
|
arg_str = 'not(@*)'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
r = split(r'([:=])', text, maxsplit=1)
|
r = split(r'([:=$^])', text, maxsplit=1)
|
||||||
len_r = len(r)
|
len_r = len(r)
|
||||||
len_r0 = len(r[0])
|
len_r0 = len(r[0])
|
||||||
if len_r != 3 and len_r0 > 1:
|
if len_r != 3 and len_r0 > 1:
|
||||||
arg_str = 'normalize-space(text())' if r[0] in ('@text()', '@tx()') else f'{r[0]}'
|
arg_str = 'normalize-space(text())' if r[0] in ('@text()', '@tx()') else f'{r[0]}'
|
||||||
|
|
||||||
elif len_r == 3 and len_r0 > 1:
|
elif len_r == 3 and len_r0 > 1:
|
||||||
if r[1] == '=': # 精确查找
|
symbol = r[1]
|
||||||
|
if symbol == '=': # 精确查找
|
||||||
arg = '.' if r[0] in ('@text()', '@tx()') else r[0]
|
arg = '.' if r[0] in ('@text()', '@tx()') else r[0]
|
||||||
arg_str = f'{arg}={_make_search_str(r[2])}'
|
arg_str = f'{arg}={_make_search_str(r[2])}'
|
||||||
|
|
||||||
else: # 模糊查找
|
elif symbol == '^': # 开头开头
|
||||||
|
if r[0] in ('@text()', '@tx()'):
|
||||||
|
txt_str = f'/text()[starts-with(., {_make_search_str(r[2])})]/..'
|
||||||
|
arg_str = ''
|
||||||
|
else:
|
||||||
|
arg_str = f"starts-with({r[0]},{_make_search_str(r[2])})"
|
||||||
|
|
||||||
|
elif symbol == '$': # 匹配结尾
|
||||||
|
if r[0] in ('@text()', '@tx()'):
|
||||||
|
txt_str = f'/text()[substring(., string-length(.) - string-length({_make_search_str(r[2])}) +1) ' \
|
||||||
|
f'= {_make_search_str(r[2])}]/..'
|
||||||
|
arg_str = ''
|
||||||
|
else:
|
||||||
|
arg_str = f'substring({r[0]}, string-length({r[0]}) - string-length({_make_search_str(r[2])}) +1)' \
|
||||||
|
f' = {_make_search_str(r[2])}'
|
||||||
|
|
||||||
|
elif symbol == ':': # 模糊查找
|
||||||
if r[0] in ('@text()', '@tx()'):
|
if r[0] in ('@text()', '@tx()'):
|
||||||
txt_str = f'/text()[contains(., {_make_search_str(r[2])})]/..'
|
txt_str = f'/text()[contains(., {_make_search_str(r[2])})]/..'
|
||||||
arg_str = ''
|
arg_str = ''
|
||||||
else:
|
else:
|
||||||
arg_str = f"contains({r[0]},{_make_search_str(r[2])})"
|
arg_str = f"contains({r[0]},{_make_search_str(r[2])})"
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError(f'符号不正确:{symbol}')
|
||||||
|
|
||||||
if arg_str:
|
if arg_str:
|
||||||
arg_list.append(arg_str)
|
arg_list.append(arg_str)
|
||||||
arg_str = ' and '.join(arg_list)
|
arg_str = ' and '.join(arg_list)
|
||||||
@ -161,7 +189,7 @@ def _make_multi_xpath_str(tag: str, text: str, _and: bool = True) -> str:
|
|||||||
args = text.split('@@') if _and else text.split('@|')
|
args = text.split('@@') if _and else text.split('@|')
|
||||||
|
|
||||||
for arg in args[1:]:
|
for arg in args[1:]:
|
||||||
r = split(r'([:=])', arg, maxsplit=1)
|
r = split(r'([:=$^])', arg, maxsplit=1)
|
||||||
arg_str = ''
|
arg_str = ''
|
||||||
len_r = len(r)
|
len_r = len(r)
|
||||||
|
|
||||||
@ -176,11 +204,23 @@ def _make_multi_xpath_str(tag: str, text: str, _and: bool = True) -> str:
|
|||||||
|
|
||||||
elif len_r == 3: # 属性名和内容都有
|
elif len_r == 3: # 属性名和内容都有
|
||||||
arg = '.' if r[0] in ('text()', 'tx()') else f'@{r[0]}'
|
arg = '.' if r[0] in ('text()', 'tx()') else f'@{r[0]}'
|
||||||
if r[1] == '=':
|
symbol = r[1]
|
||||||
|
if symbol == '=':
|
||||||
arg_str = f'{arg}={_make_search_str(r[2])}'
|
arg_str = f'{arg}={_make_search_str(r[2])}'
|
||||||
else:
|
|
||||||
|
elif symbol == ':':
|
||||||
arg_str = f'contains({arg},{_make_search_str(r[2])})'
|
arg_str = f'contains({arg},{_make_search_str(r[2])})'
|
||||||
|
|
||||||
|
elif symbol == '^':
|
||||||
|
arg_str = f'starts-with({arg},{_make_search_str(r[2])})'
|
||||||
|
|
||||||
|
elif symbol == '$':
|
||||||
|
arg_str = f'substring({arg}, string-length({arg}) - string-length({_make_search_str(r[2])}) +1) ' \
|
||||||
|
f'= {_make_search_str(r[2])}'
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError(f'符号不正确:{symbol}')
|
||||||
|
|
||||||
if arg_str and ignore:
|
if arg_str and ignore:
|
||||||
arg_str = f'not({arg_str})'
|
arg_str = f'not({arg_str})'
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ class DriverOptions(Options):
|
|||||||
self._experimental_options = options_dict.get('experimental_options', {})
|
self._experimental_options = options_dict.get('experimental_options', {})
|
||||||
self._debugger_address = options_dict.get('debugger_address', None)
|
self._debugger_address = options_dict.get('debugger_address', None)
|
||||||
self.page_load_strategy = options_dict.get('page_load_strategy', 'normal')
|
self.page_load_strategy = options_dict.get('page_load_strategy', 'normal')
|
||||||
|
self.system_user_path = options_dict.get('system_user_path', False)
|
||||||
|
|
||||||
for arg in self._arguments:
|
for arg in self._arguments:
|
||||||
if arg.startswith('--user-data-dir='):
|
if arg.startswith('--user-data-dir='):
|
||||||
@ -50,6 +51,7 @@ class DriverOptions(Options):
|
|||||||
self.ini_path = None
|
self.ini_path = None
|
||||||
self.timeouts = {'implicit': 10, 'pageLoad': 30, 'script': 30}
|
self.timeouts = {'implicit': 10, 'pageLoad': 30, 'script': 30}
|
||||||
self._debugger_address = '127.0.0.1:9222'
|
self._debugger_address = '127.0.0.1:9222'
|
||||||
|
self.system_user_path = False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def driver_path(self):
|
def driver_path(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user