def get_loc_from_str(loc: str) -> tuple: """处理元素查找语句 \n 查找方式:属性、tag name及属性、文本、xpath、css selector \n =表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n 示例: \n @class:ele_class - class含有ele_class的元素 \n @class=ele_class - class等于ele_class的元素 \n @class - 带class属性的元素 \n tag:div - div元素 \n tag:div@class:ele_class - class含有ele_class的div元素 \n tag:div@class=ele_class - class等于ele_class的div元素 \n tag:div@text():search_text - 文本含有search_text的div元素 \n tag:div@text()=search_text - 文本等于search_text的div元素 \n text:search_text - 文本含有search_text的元素 \n text=search_text - 文本等于search_text的元素 \n xpath://div[@class="ele_class"] \n css:div.ele_class \n """ loc_by = 'xpath' if loc.startswith('@'): # 根据属性查找 r = re_SPLIT(r'([:=])', loc[1:], maxsplit=1) if len(r) == 3: mode = 'exact' if r[1] == '=' else 'fuzzy' loc_str = _make_xpath_str('*', f'@{r[0]}', r[2], mode) else: loc_str = f'//*[@{loc[1:]}]' elif loc.startswith(('tag=', 'tag:')): # 根据tag name查找 if '@' not in loc[4:]: loc_str = f'//*[name()="{loc[4:]}"]' else: at_lst = loc[4:].split('@', maxsplit=1) r = re_SPLIT(r'([:=])', at_lst[1], maxsplit=1) if len(r) == 3: mode = 'exact' if r[1] == '=' else 'fuzzy' arg_str = r[0] if r[0] == 'text()' else f'@{r[0]}' loc_str = _make_xpath_str(at_lst[0], arg_str, r[2], mode) else: loc_str = f'//*[name()="{at_lst[0]}" and @{r[0]}]' elif loc.startswith(('text=', 'text:')): # 根据文本查找 if len(loc) > 5: mode = 'exact' if loc[4] == '=' else 'fuzzy' loc_str = _make_xpath_str('*', 'text()', loc[5:], mode) else: loc_str = '//*[not(text())]' elif loc.startswith(('xpath=', 'xpath:')): # 用xpath查找 loc_str = loc[6:] elif loc.startswith(('css=', 'css:')): # 用css selector查找 loc_by = 'css selector' loc_str = loc[4:] else: if loc: loc_str = _make_xpath_str('*', 'text()', loc, 'fuzzy') else: loc_str = '//*[not(text())]' return loc_by, loc_str
def get_css_from_str(loc: str) -> tuple: """处理元素查找语句 \n 查找方式:属性、tag name及属性、文本、css selector \n =表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n =表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n 示例: \n @class:ele_class - class含有ele_class的元素 \n @class=ele_class - class等于ele_class的元素 \n @class - 带class属性的元素 \n tag:div - div元素 \n tag:div@class:ele_class - class含有ele_class的div元素 \n tag:div@class=ele_class - class等于ele_class的div元素 \n tag:div@text():search_text - 文本含有search_text的div元素 \n tag:div@text()=search_text - 文本等于search_text的div元素 \n text:search_text - 文本含有search_text的元素 \n text=search_text - 文本等于search_text的元素 \n css:div.ele_class \n """ loc_by = 'css selector' if loc.startswith('@'): # 根据属性查找 r = re_SPLIT(r'([:=])', loc[1:], maxsplit=1) if len(r) == 3: mode = '=' if r[1] == '=' else '*=' loc_str = f'*[{r[0]}{mode}{r[2]}]' else: loc_str = f'*[{loc[1:]}]' elif loc.startswith(('tag=', 'tag:')): # 根据tag name查找 if '@' not in loc[4:]: loc_str = f'{loc[4:]}' else: at_lst = loc[4:].split('@', maxsplit=1) r = re_SPLIT(r'([:=])', at_lst[1], maxsplit=1) if len(r) == 3: if r[0] == 'text()': match = 'exact' if r[1] == '=' else 'fuzzy' return 'text', r[2], at_lst[0], match mode = '=' if r[1] == '=' else '*=' loc_str = f'{at_lst[0]}[{r[0]}{mode}"{r[2]}"]' else: loc_str = f'{at_lst[0]}[{r[0]}]' elif loc.startswith(('css=', 'css:')): # 用css selector查找 loc_str = loc[4:] elif loc.startswith(('xpath=', 'xpath:')): # 用xpath查找 raise ValueError('不支持xpath') elif loc.startswith(('text=', 'text:')): # 根据文本查找 match = 'exact' if loc[4] == '=' else 'fuzzy' return 'text', loc[5:], '', match else: # 根据文本模糊查找 return 'text', loc, '', 'fuzzy' return loc_by, loc_str
def str_to_loc(loc: str) -> tuple: """处理元素查找语句 \n 查找方式:属性、tag name及属性、文本、xpath、css selector、id、class \n @表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n 示例: \n .ele_class - class等于ele_class的元素 \n .:ele_class - class含有ele_class的元素 \n #ele_id - id等于ele_id的元素 \n #:ele_id - id含有ele_id的元素 \n @class:ele_class - class含有ele_class的元素 \n @class=ele_class - class等于ele_class的元素 \n @class - 带class属性的元素 \n tag:div - div元素 \n tag:div@class:ele_class - class含有ele_class的div元素 \n tag:div@class=ele_class - class等于ele_class的div元素 \n tag:div@text():search_text - 文本含有search_text的div元素 \n tag:div@text()=search_text - 文本等于search_text的div元素 \n text:search_text - 文本含有search_text的元素 \n text=search_text - 文本等于search_text的元素 \n xpath://div[@class="ele_class"] - 用xpath查找 \n css:div.ele_class - 用css selector查找 """ loc_by = 'xpath' # .和#替换为class和id查找 if loc.startswith('.'): if loc.startswith(( '.=', '.:', )): loc = loc.replace('.', '@class', 1) else: loc = loc.replace('.', '@class=', 1) if loc.startswith('#'): if loc.startswith(( '#=', '#:', )): loc = loc.replace('#', '@id', 1) else: loc = loc.replace('#', '@id=', 1) # 根据属性查找 if loc.startswith('@'): r = re_SPLIT(r'([:=])', loc[1:], maxsplit=1) if len(r) == 3: mode = 'exact' if r[1] == '=' else 'fuzzy' loc_str = _make_xpath_str('*', f'@{r[0]}', r[2], mode) else: loc_str = f'//*[@{loc[1:]}]' # 根据tag name查找 elif loc.startswith(('tag=', 'tag:')): if '@' not in loc[4:]: loc_str = f'//*[name()="{loc[4:]}"]' else: at_lst = loc[4:].split('@', maxsplit=1) r = re_SPLIT(r'([:=])', at_lst[1], maxsplit=1) if len(r) == 3: mode = 'exact' if r[1] == '=' else 'fuzzy' arg_str = r[0] if r[0] == 'text()' else f'@{r[0]}' loc_str = _make_xpath_str(at_lst[0], arg_str, r[2], mode) else: loc_str = f'//*[name()="{at_lst[0]}" and @{r[0]}]' # 根据文本查找 elif loc.startswith(('text=', 'text:')): if len(loc) > 5: mode = 'exact' if loc[4] == '=' else 'fuzzy' loc_str = _make_xpath_str('*', 'text()', loc[5:], mode) else: loc_str = '//*[not(text())]' # 用xpath查找 elif loc.startswith(('xpath=', 'xpath:')): loc_str = loc[6:] # 用css selector查找 elif loc.startswith(('css=', 'css:')): loc_by = 'css selector' loc_str = loc[4:] # 根据文本模糊查找 else: if loc: loc_str = _make_xpath_str('*', 'text()', loc, 'fuzzy') else: loc_str = '//*[not(text())]' return loc_by, loc_str
def str_to_css_loc(loc: str) -> tuple: """处理元素查找语句 \n 查找方式:属性、tag name及属性、文本、css selector \n @表示属性,.表示class,#表示id,=表示精确匹配,:表示模糊匹配,无控制字符串时默认搜索该字符串 \n 示例: \n .ele_class - class为ele_class的元素 \n .:ele_class - class含有ele_class的元素 \n #ele_id - id为ele_id的元素 \n #:ele_id - id含有ele_id的元素 \n @class:ele_class - class含有ele_class的元素 \n @class=ele_class - class等于ele_class的元素 \n @class - 带class属性的元素 \n tag:div - div元素 \n tag:div@class:ele_class - class含有ele_class的div元素 \n tag:div@class=ele_class - class等于ele_class的div元素 \n tag:div@text():search_text - 文本含有search_text的div元素 \n tag:div@text()=search_text - 文本等于search_text的div元素 \n text:search_text - 文本含有search_text的元素 \n text=search_text - 文本等于search_text的元素 \n css:div.ele_class - 符合css selector的元素 \n """ loc_by = 'css selector' # .和#替换为class和id查找 if loc.startswith('.'): if loc.startswith(( '.=', '.:', )): loc = loc.replace('.', '@class', 1) else: loc = loc.replace('.', '@class=', 1) if loc.startswith('#'): if loc.startswith(( '#=', '#:', )): loc = loc.replace('#', '@id', 1) else: loc = loc.replace('#', '@id=', 1) # 根据属性查找 if loc.startswith('@'): r = re_SPLIT(r'([:=])', loc[1:], maxsplit=1) if len(r) == 3: mode = '=' if r[1] == '=' else '*=' loc_str = f'*[{r[0]}{mode}{r[2]}]' else: loc_str = f'*[{loc[1:]}]' # 根据tag name查找 elif loc.startswith(('tag=', 'tag:')): if '@' not in loc[4:]: loc_str = f'{loc[4:]}' else: at_lst = loc[4:].split('@', maxsplit=1) r = re_SPLIT(r'([:=])', at_lst[1], maxsplit=1) if len(r) == 3: if r[0] == 'text()': match = 'exact' if r[1] == '=' else 'fuzzy' return 'text', r[2], at_lst[0], match mode = '=' if r[1] == '=' else '*=' loc_str = f'{at_lst[0]}[{r[0]}{mode}"{r[2]}"]' else: loc_str = f'{at_lst[0]}[{r[0]}]' # 用css selector查找 elif loc.startswith(('css=', 'css:')): loc_str = loc[4:] # 用xpath查找 elif loc.startswith(('xpath=', 'xpath:')): raise ValueError('不支持xpath') # 根据文本查找 elif loc.startswith(('text=', 'text:')): match = 'exact' if loc[4] == '=' else 'fuzzy' return 'text', loc[5:], '', match # 根据文本模糊查找 else: return 'text', loc, '', 'fuzzy' return loc_by, loc_str