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 pathlib import Path
|
||||
from time import perf_counter, sleep, time
|
||||
from urllib.parse import urlparse
|
||||
from warnings import warn
|
||||
|
||||
from requests import Session
|
||||
@ -990,11 +991,10 @@ class ChromiumBaseSetter(object):
|
||||
result_cookies = []
|
||||
for cookie in cookies:
|
||||
if not cookie.get('domain', None):
|
||||
continue
|
||||
c = {'value': '' if cookie['value'] is None else cookie['value'],
|
||||
'name': cookie['name'],
|
||||
'domain': cookie['domain']}
|
||||
result_cookies.append(c)
|
||||
cookie['domain'] = urlparse(self._page.url).netloc
|
||||
result_cookies.append({'value': '' if cookie['value'] is None else cookie['value'],
|
||||
'name': cookie['name'],
|
||||
'domain': cookie['domain']})
|
||||
self._page.run_cdp_loaded('Network.setCookies', cookies=result_cookies)
|
||||
|
||||
def upload_files(self, files):
|
||||
@ -1192,3 +1192,4 @@ class PageScrollSetter(object):
|
||||
raise TypeError('on_off必须为bool。')
|
||||
b = 'smooth' if on_off else 'auto'
|
||||
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):
|
||||
self._page = page
|
||||
|
||||
@property
|
||||
def window_state(self):
|
||||
"""返回窗口状态:normal、fullscreen、maximized、 minimized"""
|
||||
return self._get_browser_rect()['windowState']
|
||||
|
||||
@property
|
||||
def browser_location(self):
|
||||
"""返回浏览器在屏幕上的坐标,左上角为(0, 0)"""
|
||||
|
@ -116,6 +116,9 @@ class ChromiumTabRect(object):
|
||||
def __init__(self, page: ChromiumPage):
|
||||
self._page: ChromiumPage = ...
|
||||
|
||||
@property
|
||||
def window_state(self) -> str: ...
|
||||
|
||||
@property
|
||||
def browser_location(self) -> Tuple[int, int]: ...
|
||||
|
||||
|
@ -99,7 +99,7 @@ def set_prefs(opt):
|
||||
prefs = opt.preferences
|
||||
del_list = opt._prefs_to_del
|
||||
else:
|
||||
prefs = opt.experimental_options.get('prefs', None)
|
||||
prefs = opt.experimental_options.get('prefs', [])
|
||||
del_list = []
|
||||
|
||||
if not opt.user_data_path:
|
||||
|
@ -36,19 +36,19 @@ def get_loc(loc, translate_css=False):
|
||||
|
||||
def str_to_loc(loc):
|
||||
"""处理元素查找语句
|
||||
查找方式:属性、tag name及属性、文本、xpath、css selector、id、class
|
||||
@表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串
|
||||
:param loc: 查找语法字符串
|
||||
:return: 匹配符元组
|
||||
"""
|
||||
loc_by = 'xpath'
|
||||
|
||||
if loc.startswith('.'):
|
||||
if loc.startswith(('.=', '.:',)):
|
||||
if loc.startswith(('.=', '.:', '.^', '.$')):
|
||||
loc = loc.replace('.', '@class', 1)
|
||||
else:
|
||||
loc = loc.replace('.', '@class=', 1)
|
||||
|
||||
elif loc.startswith('#'):
|
||||
if loc.startswith(('#=', '#:',)):
|
||||
if loc.startswith(('#=', '#:', '#^', '#$')):
|
||||
loc = loc.replace('#', '@id', 1)
|
||||
else:
|
||||
loc = loc.replace('#', '@id=', 1)
|
||||
@ -56,7 +56,7 @@ def str_to_loc(loc):
|
||||
elif loc.startswith(('t:', 't=')):
|
||||
loc = f'tag:{loc[2:]}'
|
||||
|
||||
elif loc.startswith(('tx:', 'tx=')):
|
||||
elif loc.startswith(('tx:', 'tx=', 'tx^', 'tx$')):
|
||||
loc = f'text{loc[2:]}'
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
@ -87,9 +87,17 @@ def str_to_loc(loc):
|
||||
# 根据文本查找
|
||||
elif loc.startswith('text='):
|
||||
loc_str = f'//*[text()={_make_search_str(loc[5:])}]'
|
||||
|
||||
elif loc.startswith('text:') and loc != 'text:':
|
||||
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查找
|
||||
elif loc.startswith(('xpath:', 'xpath=')) and loc not in ('xpath:', 'xpath='):
|
||||
loc_str = loc[6:]
|
||||
@ -100,7 +108,7 @@ def str_to_loc(loc):
|
||||
elif loc.startswith(('css:', 'css=')) and loc not in ('css:', 'css='):
|
||||
loc_by = 'css selector'
|
||||
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_str = loc[2:]
|
||||
|
||||
@ -126,24 +134,44 @@ def _make_single_xpath_str(tag: str, text: str) -> str:
|
||||
arg_str = 'not(@*)'
|
||||
|
||||
else:
|
||||
r = split(r'([:=])', text, maxsplit=1)
|
||||
r = split(r'([:=$^])', text, maxsplit=1)
|
||||
len_r = len(r)
|
||||
len_r0 = len(r[0])
|
||||
if len_r != 3 and len_r0 > 1:
|
||||
arg_str = 'normalize-space(text())' if r[0] in ('@text()', '@tx()') else f'{r[0]}'
|
||||
|
||||
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_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()'):
|
||||
txt_str = f'/text()[contains(., {_make_search_str(r[2])})]/..'
|
||||
arg_str = ''
|
||||
else:
|
||||
arg_str = f"contains({r[0]},{_make_search_str(r[2])})"
|
||||
|
||||
else:
|
||||
raise ValueError(f'符号不正确:{symbol}')
|
||||
|
||||
if arg_str:
|
||||
arg_list.append(arg_str)
|
||||
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('@|')
|
||||
|
||||
for arg in args[1:]:
|
||||
r = split(r'([:=])', arg, maxsplit=1)
|
||||
r = split(r'([:=$^])', arg, maxsplit=1)
|
||||
arg_str = ''
|
||||
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: # 属性名和内容都有
|
||||
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])}'
|
||||
else:
|
||||
|
||||
elif symbol == ':':
|
||||
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:
|
||||
arg_str = f'not({arg_str})'
|
||||
|
||||
|
@ -36,6 +36,7 @@ class DriverOptions(Options):
|
||||
self._experimental_options = options_dict.get('experimental_options', {})
|
||||
self._debugger_address = options_dict.get('debugger_address', None)
|
||||
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:
|
||||
if arg.startswith('--user-data-dir='):
|
||||
@ -50,6 +51,7 @@ class DriverOptions(Options):
|
||||
self.ini_path = None
|
||||
self.timeouts = {'implicit': 10, 'pageLoad': 30, 'script': 30}
|
||||
self._debugger_address = '127.0.0.1:9222'
|
||||
self.system_user_path = False
|
||||
|
||||
@property
|
||||
def driver_path(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user