latest_tab改为返回Tab对象;Page对象的tabs属性改为tab_ids;get_tab()增加几个参数;find_tabs()改为get_tabs()且返回Tab对象

This commit is contained in:
g1879 2024-03-09 23:53:41 +08:00
parent fec3291be4
commit 29d0886975
9 changed files with 142 additions and 58 deletions

View File

@ -14,4 +14,4 @@ from ._configs.chromium_options import ChromiumOptions
from ._configs.session_options import SessionOptions
__all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__']
__version__ = '4.0.4.8'
__version__ = '4.0.4.9'

View File

@ -129,7 +129,7 @@ class Browser(object):
return len([i for i in j if i['type'] in ('page', 'webview') and not i['url'].startswith('devtools://')])
@property
def tabs(self):
def tab_ids(self):
"""返回所有标签页id组成的列表"""
j = self._driver.get(f'http://{self.address}/json').json() # 不要改用cdp因为顺序不对
return [i['id'] for i in j if i['type'] in ('page', 'webview') and not i['url'].startswith('devtools://')]
@ -139,13 +139,12 @@ class Browser(object):
"""返回浏览器进程id"""
return self._process_id
def find_tabs(self, title=None, url=None, tab_type=None, single=True):
"""查找符合条件的tab返回它们的id组成的列表
def find_tabs(self, title=None, url=None, tab_type=None):
"""查找符合条件的tab返回它们组成的列表
:param title: 要匹配title的文本
:param url: 要匹配url的文本
:param tab_type: tab类型可用列表输入多个
:param single: 是否返回首个结果的id为False返回所有信息
:return: tab id或tab列表
:return: dict格式的tab信息列表列表
"""
tabs = self._driver.get(f'http://{self.address}/json').json() # 不要改用cdp
@ -156,9 +155,8 @@ class Browser(object):
elif tab_type is not None:
raise TypeError('tab_type只能是set、list、tuple、str、None。')
r = [i for i in tabs if ((title is None or title in i['title']) and (url is None or url in i['url'])
and (tab_type is None or i['type'] in tab_type))]
return r[0]['id'] if r and single else r
return [i for i in tabs if ((title is None or title in i['title']) and (url is None or url in i['url'])
and (tab_type is None or i['type'] in tab_type))]
def close_tab(self, tab_id):
"""关闭标签页

View File

@ -40,13 +40,13 @@ class Browser(object):
def tabs_count(self) -> int: ...
@property
def tabs(self) -> List[str]: ...
def tab_ids(self) -> List[str]: ...
@property
def process_id(self) -> Optional[int]: ...
def find_tabs(self, title: str = None, url: str = None,
tab_type: Union[str, list, tuple] = None, single: bool = True) -> Union[str, List[str]]: ...
tab_type: Union[str, list, tuple] = None) -> List[dict]: ...
def close_tab(self, tab_id: str) -> None: ...

View File

@ -30,7 +30,7 @@ class Driver(object):
self.address = address
self.type = tab_type
self.owner = owner
self._debug = False
# self._debug = False
self.alert_flag = False # 标记alert出现跳过一条请求后复原
self._websocket_url = f'ws://{address}/devtools/{tab_type}/{tab_id}'
@ -180,7 +180,6 @@ class Driver(object):
def run(self, _method, **kwargs):
"""执行cdp方法
:param _method: cdp方法名
:param args: cdp参数
:param kwargs: cdp参数
:return: 执行结果
"""

View File

@ -124,14 +124,14 @@ class ChromiumPage(ChromiumBase):
return self.browser.tabs_count
@property
def tabs(self):
def tab_ids(self):
"""返回所有标签页id组成的列表"""
return self.browser.tabs
return self.browser.tab_ids
@property
def latest_tab(self):
"""返回最新的标签页id,最新标签页指最后创建或最后被激活的"""
return self.tabs[0]
"""返回最新的标签页对象,最新标签页指最后创建或最后被激活的"""
return self.get_tab(self.tab_ids[0])
@property
def process_id(self):
@ -148,32 +148,51 @@ class ChromiumPage(ChromiumBase):
"""
return get_pdf(self, path, name, kwargs) if as_pdf else get_mhtml(self, path, name)
def get_tab(self, id_or_num=None):
"""获取一个标签页对象
:param id_or_num: 要获取的标签页id或序号为None时获取当前tab序号从1开始可传入负数获取倒数第几个不是视觉排列顺序而是激活顺序
:return: 标签页对象
def get_tab(self, id_or_num=None, title=None, url=None, tab_type=None, as_id=False):
"""获取一个标签页对象id_or_num不为None时后面几个参数无效
:param id_or_num: 要获取的标签页id或序号序号从1开始可传入负数获取倒数第几个不是视觉排列顺序而是激活顺序
:param title: 要匹配title的文本模糊匹配为None则匹配所有
:param url: 要匹配url的文本模糊匹配为None则匹配所有
:param tab_type: tab类型可用列表输入多个 'page', 'iframe' 为None则匹配所有
:param as_id: 是否返回标签页id而不是标签页对象
:return: ChromiumTab对象
"""
with self._lock:
if id_or_num is not None:
if isinstance(id_or_num, str):
return ChromiumTab(self, id_or_num)
id_or_num = id_or_num
elif isinstance(id_or_num, int):
return ChromiumTab(self, self.tabs[id_or_num - 1 if id_or_num > 0 else id_or_num])
elif id_or_num is None:
return ChromiumTab(self, self.tab_id)
id_or_num = self.tab_ids[id_or_num - 1 if id_or_num > 0 else id_or_num]
elif isinstance(id_or_num, ChromiumTab):
return id_or_num
else:
raise TypeError(f'id_or_num需传入tab id或序号{id_or_num}')
return id_or_num.tab_id if as_id else id_or_num
def find_tabs(self, title=None, url=None, tab_type=None, single=True):
"""查找符合条件的tab返回它们的id组成的列表
:param title: 要匹配title的文本
:param url: 要匹配url的文本
:param tab_type: tab类型可用列表输入多个
:param single: 是否返回首个结果的id为False返回所有信息
:return: tab id或tab列表
elif title == url == tab_type is None:
id_or_num = self.tab_id
else:
id_or_num = self._browser.find_tabs(title, url, tab_type)
if id_or_num:
id_or_num = id_or_num[0]
else:
return None
if as_id:
return id_or_num
with self._lock:
return ChromiumTab(self, id_or_num)
def get_tabs(self, title=None, url=None, tab_type=None, as_id=False):
"""查找符合条件的tab返回它们组成的列表
:param title: 要匹配title的文本模糊匹配为None则匹配所有
:param url: 要匹配url的文本模糊匹配为None则匹配所有
:param tab_type: tab类型可用列表输入多个 'page', 'iframe' 为None则匹配所有
:param as_id: 是否返回标签页id而不是标签页对象
:return: ChromiumTab对象组成的列表
"""
return self._browser.find_tabs(title, url, tab_type, single)
if as_id:
return [tab['id'] for tab in self._browser.find_tabs(title, url, tab_type)]
with self._lock:
return [ChromiumTab(self, tab['id']) for tab in self._browser.find_tabs(title, url, tab_type)]
def new_tab(self, url=None, new_window=False, background=False, new_context=False):
"""新建一个标签页
@ -219,7 +238,7 @@ class ChromiumPage(ChromiumBase):
:param others: 是否关闭指定标签页之外的
:return: None
"""
all_tabs = set(self.tabs)
all_tabs = set(self.tab_ids)
if isinstance(tabs_or_ids, str):
tabs = {tabs_or_ids}
elif isinstance(tabs_or_ids, ChromiumTab):
@ -269,6 +288,22 @@ class ChromiumPage(ChromiumBase):
"""
self.close_tabs(tabs_or_ids, True)
@property
def tabs(self):
"""返回所有标签页id组成的列表"""
return self.browser.tab_ids
def find_tabs(self, title=None, url=None, tab_type=None, single=True):
"""查找符合条件的tab返回它们组成的列表
:param title: 要匹配title的文本
:param url: 要匹配url的文本
:param tab_type: tab类型可用列表输入多个
:param single: 是否返回首个结果的id为False返回所有信息
:return: tab id或tab列表
"""
r = self._browser.find_tabs(title, url, tab_type)
return r[0]['id'] if r and single else r
def handle_options(addr_or_opts):
"""设置浏览器启动属性

View File

@ -51,13 +51,13 @@ class ChromiumPage(ChromiumBase):
def tabs_count(self) -> int: ...
@property
def tabs(self) -> List[str]: ...
def tab_ids(self) -> List[str]: ...
@property
def wait(self) -> PageWaiter: ...
@property
def latest_tab(self) -> str: ...
def latest_tab(self) -> Union[ChromiumTab, ChromiumPage]: ...
@property
def process_id(self) -> Optional[int]: ...
@ -86,10 +86,18 @@ class ChromiumPage(ChromiumBase):
generateTaggedPDF: bool = ...,
generateDocumentOutline: bool = ...) -> Union[bytes, str]: ...
def get_tab(self, tab_id: Union[str, ChromiumTab, int] = None) -> ChromiumTab: ...
def get_tab(self,
id_or_num: Union[str, ChromiumTab, int] = None,
title: str = None,
url: str = None,
tab_type: Union[str, list, tuple] = None,
as_id: bool = False) -> Union[ChromiumTab, str, None]: ...
def find_tabs(self, title: str = None, url: str = None,
tab_type: Union[str, list, tuple] = None, single: bool = True) -> Union[str, List[str]]: ...
def get_tabs(self,
title: str = None,
url: str = None,
tab_type: Union[str, list, tuple] = None,
as_id: bool = False) -> Union[List[ChromiumTab], List[str]]: ...
def new_tab(self, url: str = None, new_window: bool = False, background: bool = False,
new_context: bool = False) -> ChromiumTab: ...

View File

@ -308,21 +308,51 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
elif self._mode == 'd':
return super(SessionPage, self).cookies(as_dict, all_domains, all_info)
def get_tab(self, id_or_num=None):
"""获取一个标签页对象
:param id_or_num: 要获取的标签页id或序号为None时获取当前tab序号不是视觉排列顺序而是激活顺序
:return: 标签页对象
def get_tab(self, id_or_num=None, title=None, url=None, tab_type=None, as_id=False):
"""获取一个标签页对象id_or_num不为None时后面几个参数无效
:param id_or_num: 要获取的标签页id或序号序号从1开始可传入负数获取倒数第几个不是视觉排列顺序而是激活顺序
:param title: 要匹配title的文本模糊匹配为None则匹配所有
:param url: 要匹配url的文本模糊匹配为None则匹配所有
:param tab_type: tab类型可用列表输入多个 'page', 'iframe' 为None则匹配所有
:param as_id: 是否返回标签页id而不是标签页对象
:return: WebPageTab对象
"""
if isinstance(id_or_num, str):
return WebPageTab(self, id_or_num)
elif isinstance(id_or_num, int):
return WebPageTab(self, self.tabs[id_or_num])
elif id_or_num is None:
return WebPageTab(self, self.tab_id)
elif isinstance(id_or_num, WebPageTab):
return id_or_num
if id_or_num is not None:
if isinstance(id_or_num, str):
id_or_num = id_or_num
elif isinstance(id_or_num, int):
id_or_num = self.tab_ids[id_or_num - 1 if id_or_num > 0 else id_or_num]
elif isinstance(id_or_num, WebPageTab):
return id_or_num.tab_id if as_id else id_or_num
elif title == url == tab_type is None:
id_or_num = self.tab_id
else:
raise TypeError(f'id_or_num需传入tab id或序号{id_or_num}')
id_or_num = self._browser.find_tabs(title, url, tab_type)
if id_or_num:
id_or_num = id_or_num[0]
else:
return None
if as_id:
return id_or_num
with self._lock:
return WebPageTab(self, id_or_num)
def get_tabs(self, title=None, url=None, tab_type=None, as_id=False):
"""查找符合条件的tab返回它们组成的列表
:param title: 要匹配title的文本模糊匹配为None则匹配所有
:param url: 要匹配url的文本模糊匹配为None则匹配所有
:param tab_type: tab类型可用列表输入多个 'page', 'iframe' 为None则匹配所有
:param as_id: 是否返回标签页id而不是标签页对象
:return: ChromiumTab对象组成的列表
"""
if as_id:
return [tab['id'] for tab in self._browser.find_tabs(title, url, tab_type)]
with self._lock:
return [WebPageTab(self, tab['id']) for tab in self._browser.find_tabs(title, url, tab_type)]
def new_tab(self, url=None, new_window=False, background=False, new_context=False):
"""新建一个标签页

View File

@ -127,7 +127,18 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
all_domains: bool = False,
all_info: bool = False) -> Union[dict, list]: ...
def get_tab(self, id_or_num: Union[str, WebPageTab, int] = None) -> WebPageTab: ...
def get_tab(self,
id_or_num: Union[str, WebPageTab, int] = None,
title: str = None,
url: str = None,
tab_type: Union[str, list, tuple] = None,
as_id: bool = False) -> Union[WebPageTab, str, None]: ...
def get_tabs(self,
title: str = None,
url: str = None,
tab_type: Union[str, list, tuple] = None,
as_id: bool = False) -> Union[List[WebPageTab], List[str]]: ...
def new_tab(self,
url: str = None,
@ -162,6 +173,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
verify: Any | None = ...,
cert: Any | None = ...) -> Union[bool, Response]: ...
@property
def latest_tab(self) -> Union[WebPageTab, WebPage]: ...
@property
def set(self) -> WebPageSetter: ...

View File

@ -70,7 +70,7 @@ class ChromiumBaseSetter(BasePageSetter):
class TabSetter(ChromiumBaseSetter):
_owner: ChromiumTab = ...
def __init__(self, owner: Union[ChromiumTab, WebPage]): ...
def __init__(self, owner: Union[ChromiumTab, WebPageTab, WebPage, ChromiumPage]): ...
@property
def window(self) -> WindowSetter: ...