From fc1e39cd3c7e9c78726adda93bb8f569cce49542 Mon Sep 17 00:00:00 2001 From: g1879 Date: Sun, 2 Apr 2023 19:26:40 +0800 Subject: [PATCH] =?UTF-8?q?3.2.23=E5=85=83=E7=B4=A0=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0focus()=EF=BC=9BChromiumPage=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0find=5Ftabs()=EF=BC=9B=E5=8F=AF=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E7=82=B9=E5=87=BB=E6=97=B6=E6=8A=9B=E5=87=BA?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/chromium_element.py | 17 +++++++++++++---- DrissionPage/chromium_element.pyi | 12 +++++++----- DrissionPage/chromium_page.py | 14 ++++++++++++++ DrissionPage/chromium_page.pyi | 2 ++ DrissionPage/common.py | 1 + DrissionPage/commons/constants.py | 1 + DrissionPage/errors.py | 4 ++++ setup.py | 3 ++- 8 files changed, 44 insertions(+), 10 deletions(-) diff --git a/DrissionPage/chromium_element.py b/DrissionPage/chromium_element.py index 9bd4f0d..d9d0b6f 100644 --- a/DrissionPage/chromium_element.py +++ b/DrissionPage/chromium_element.py @@ -15,7 +15,7 @@ from .commons.keys import keys_to_typing, keyDescriptionForString, keyDefinition from .commons.locator import get_loc from .commons.web import make_absolute_link, get_ele_txt, format_html, is_js_func, location_in_viewport, offset_scroll from .errors import ContextLossError, ElementLossError, JavaScriptError, NoRectError, ElementNotFoundError, \ - CallMethodError, NoResourceError + CallMethodError, NoResourceError, CanNotClickError from .session_element import make_session_ele @@ -531,7 +531,7 @@ class ChromiumElement(DrissionElement): if clear and vals not in ('\n', '\ue007'): self.clear(by_js=False) else: - self._focus() + self._input_focus() # ------------处理字符------------- if not isinstance(vals, (tuple, list)): @@ -558,10 +558,17 @@ class ChromiumElement(DrissionElement): self.run_js("this.value='';") else: - self._focus() + self._input_focus() self.input(('\ue009', 'a', '\ue017'), clear=False) - def _focus(self): + def _input_focus(self): + """输入前使元素获取焦点""" + try: + self.page.run_cdp('DOM.focus', backendNodeId=self._backend_id) + except Exception: + self.click(by_js=None) + + def focus(self): """使元素获取焦点""" try: self.page.run_cdp('DOM.focus', backendNodeId=self._backend_id) @@ -1769,6 +1776,8 @@ class Click(object): self._ele.run_js('this.click();') return True + if Settings.raise_click_failed: + raise CanNotClickError return False def right(self): diff --git a/DrissionPage/chromium_element.pyi b/DrissionPage/chromium_element.pyi index f7bd4ba..ee1072e 100644 --- a/DrissionPage/chromium_element.pyi +++ b/DrissionPage/chromium_element.pyi @@ -189,7 +189,9 @@ class ChromiumElement(DrissionElement): def clear(self, by_js: bool = False) -> None: ... - def _focus(self) -> None: ... + def _input_focus(self) -> None: ... + + def focus(self) -> None: ... def hover(self, offset_x: int = None, offset_y: int = None) -> None: ... @@ -445,13 +447,13 @@ class Click(object): def __init__(self, ele: ChromiumElement): self._ele: ChromiumElement = ... - def __call__(self, by_js: bool = False, timeout: float = 1) -> bool: ... + def __call__(self, by_js: Union[None, bool] = False, timeout: float = 1) -> bool: ... - def left(self, by_js: bool = False, timeout: float = 1) -> bool: ... + def left(self, by_js: Union[None, bool] = False, timeout: float = 1) -> bool: ... - def right(self): ... + def right(self) -> None: ... - def middle(self): ... + def middle(self) -> None: ... def at(self, offset_x: int = None, offset_y: int = None, button='left') -> None: ... diff --git a/DrissionPage/chromium_page.py b/DrissionPage/chromium_page.py index a0b3bad..b52de76 100644 --- a/DrissionPage/chromium_page.py +++ b/DrissionPage/chromium_page.py @@ -194,6 +194,20 @@ class ChromiumPage(ChromiumBase): tab_id = tab_id or self.tab_id return ChromiumTab(self, tab_id) + def find_tabs(self, text, by_title=True, by_url=None): + """查找符合条件的tab,返回它们的id组成的列表 + :param text: 查询条件 + :param by_title: 是否匹配title + :param by_url: 是否匹配url + :return: tab id组成的列表 + """ + if not (by_title or by_url): + return self.tabs + + tabs = self._control_session.get(f'http://{self.address}/json').json() # 不要改用cdp + return [i['id'] for i in tabs if i['type'] == 'page' and ((by_url and text in i['url']) or + (by_title and text in i['title']))] + def new_tab(self, url=None, switch_to=True): """新建一个标签页,该标签页在最后面 :param url: 新标签页跳转到的网址 diff --git a/DrissionPage/chromium_page.pyi b/DrissionPage/chromium_page.pyi index 4b9e4cd..f9e271f 100644 --- a/DrissionPage/chromium_page.pyi +++ b/DrissionPage/chromium_page.pyi @@ -81,6 +81,8 @@ class ChromiumPage(ChromiumBase): def get_tab(self, tab_id: str = None) -> ChromiumTab: ... + def find_tabs(self, text: str, by_title: bool = True, by_url: bool = None) -> List[str]: ... + def new_tab(self, url: str = None, switch_to: bool = True) -> str: ... def to_main_tab(self) -> None: ... diff --git a/DrissionPage/common.py b/DrissionPage/common.py index 9e2ba98..f1225cc 100644 --- a/DrissionPage/common.py +++ b/DrissionPage/common.py @@ -11,3 +11,4 @@ from .session_element import make_session_ele from .action_chains import ActionChains from .commons.keys import Keys from .commons.by import By +from .commons.constants import Settings diff --git a/DrissionPage/commons/constants.py b/DrissionPage/commons/constants.py index bcfc6fa..c06c2c4 100644 --- a/DrissionPage/commons/constants.py +++ b/DrissionPage/commons/constants.py @@ -12,6 +12,7 @@ ERROR = 'error' class Settings(object): raise_ele_not_found = False + raise_click_failed = False class NoneElement(object): diff --git a/DrissionPage/errors.py b/DrissionPage/errors.py index 20805ee..3bcfca0 100644 --- a/DrissionPage/errors.py +++ b/DrissionPage/errors.py @@ -50,3 +50,7 @@ class BrowserConnectError(BaseError): class NoResourceError(BaseError): _info = '该元素无可保存的内容或保存失败。' + + +class CanNotClickError(BaseError): + _info = '该元素无法滚动到视口或被遮挡,无法点击。' diff --git a/setup.py b/setup.py index 8e131f8..7c81a24 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh: setup( name="DrissionPage", - version="3.2.21", + version="3.2.23", author="g1879", author_email="g1879@qq.com", description="Python based web automation tool. It can control the browser and send and receive data packets.", @@ -21,6 +21,7 @@ setup( install_requires=[ 'lxml', 'requests', + 'cssselect', 'DownloadKit>=0.5.3', 'FlowViewer', 'websocket-client',