diff --git a/DrissionPage/__init__.py b/DrissionPage/__init__.py index 01c6967..5861945 100644 --- a/DrissionPage/__init__.py +++ b/DrissionPage/__init__.py @@ -13,4 +13,4 @@ from ._configs.chromium_options import ChromiumOptions from ._configs.session_options import SessionOptions __all__ = ['ChromiumPage', 'ChromiumOptions', 'SessionOptions', 'SessionPage', 'WebPage', '__version__'] -__version__ = '4.0.0b18' +__version__ = '4.0.0b19' diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index f09b089..ebf0796 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -688,14 +688,18 @@ class ChromiumElement(DrissionElement): if obj_id: return self.page.run_cdp('DOM.requestNode', objectId=obj_id)['nodeId'] else: - return self.page.run_cdp('DOM.describeNode', backendNodeId=backend_id)['node']['nodeId'] + n = self.page.run_cdp('DOM.describeNode', backendNodeId=backend_id)['node'] + self._tag = n['localName'] + return n['nodeId'] def _get_backend_id(self, node_id): """根据传入node id获取backend id :param node_id: :return: backend id """ - return self.page.run_cdp('DOM.describeNode', nodeId=node_id)['node']['backendNodeId'] + n = self.page.run_cdp('DOM.describeNode', nodeId=node_id)['node'] + self._tag = n['localName'] + return n['backendNodeId'] def _get_ele_path(self, mode): """返获取绝对的css路径或xpath路径""" diff --git a/DrissionPage/_units/clicker.py b/DrissionPage/_units/clicker.py index e297862..943e49c 100644 --- a/DrissionPage/_units/clicker.py +++ b/DrissionPage/_units/clicker.py @@ -34,6 +34,13 @@ class Clicker(object): :param wait_stop: 是否等待元素运动结束再执行点击 :return: 是否点击成功 """ + if self._ele.tag == 'option': + if self._ele.states.is_selected: + self._ele.parent('t:select').select.cancel_by_option(self._ele) + else: + self._ele.parent('t:select').select.by_option(self._ele) + return + if not by_js: # 模拟点击 can_click = False timeout = self._ele.page.timeout if timeout is None else timeout diff --git a/DrissionPage/_units/listener.py b/DrissionPage/_units/listener.py index 72346a6..5dd1638 100644 --- a/DrissionPage/_units/listener.py +++ b/DrissionPage/_units/listener.py @@ -88,6 +88,7 @@ class Listener(object): self._driver.run('Network.enable') self._set_callback() + self.listening = True def wait(self, count=1, timeout=None, fit_count=True, raise_err=None): """等待符合要求的数据包到达指定数量 diff --git a/DrissionPage/_units/selector.py b/DrissionPage/_units/selector.py index 9494d16..b3d9d21 100644 --- a/DrissionPage/_units/selector.py +++ b/DrissionPage/_units/selector.py @@ -109,6 +109,13 @@ class SelectElement(object): """ return self._by_loc(loc, timeout) + def by_option(self, option): + """选中单个或多个选项元素 + :param option: 定位符 + :return: None + """ + self._select_options(option, 'true') + def cancel_by_text(self, text, timeout=None): """此方法用于根据text值取消选择项。当元素是多选列表时,可以接收list或tuple :param text: 文本,传入list或tuple可取消多项 @@ -141,6 +148,13 @@ class SelectElement(object): """ return self._by_loc(loc, timeout, True) + def cancel_by_option(self, option): + """选中单个或多个选项元素 + :param option: 定位符 + :return: None + """ + self._select_options(option, 'false') + def _by_loc(self, loc, timeout=None, cancel=False): """用定位符取消选择指定的项 :param loc: 定位符 @@ -154,13 +168,9 @@ class SelectElement(object): mode = 'false' if cancel else 'true' if self.is_multi: - for ele in eles: - ele.run_js(f'this.selected={mode};') - self._dispatch_change() - return True - - eles[0].run_js(f'this.selected={mode};') - self._dispatch_change() + self._select_options(eles, mode) + else: + self._select_options(eles[0], mode) return True def _select(self, condition, para_type='text', cancel=False, timeout=None): @@ -205,10 +215,7 @@ class SelectElement(object): break if ok: - for i in eles: - i.run_js(f'this.selected={mode};') - - self._dispatch_change() + self._select_options(eles, mode) return True return False @@ -231,14 +238,26 @@ class SelectElement(object): if ok: eles = self.options - for i in condition: - eles[i - 1].run_js(f'this.selected={mode};') - - self._dispatch_change() + eles = [eles[i - 1] for i in condition] + self._select_options(eles, mode) return True return False + def _select_options(self, option, mode): + """选中或取消某个选项 + :param option: options元素对象 + :param mode: 选中还是取消 + :return: None + """ + if isinstance(option, (list, tuple, set)): + for o in option: + o.run_js(f'this.selected={mode};') + self._dispatch_change() + else: + option.run_js(f'this.selected={mode};') + self._dispatch_change() + def _dispatch_change(self): """触发修改动作""" self._ele.run_js('this.dispatchEvent(new Event("change", {bubbles: true}));') diff --git a/DrissionPage/_units/selector.pyi b/DrissionPage/_units/selector.pyi index 55d07b6..f0d2fcc 100644 --- a/DrissionPage/_units/selector.pyi +++ b/DrissionPage/_units/selector.pyi @@ -38,6 +38,8 @@ class SelectElement(object): def by_loc(self, loc: Union[str, Tuple[str, str]], timeout: float = None) -> bool: ... + def by_option(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ... + def cancel_by_text(self, text: Union[str, list, tuple], timeout: float = None) -> bool: ... def cancel_by_value(self, value: Union[str, list, tuple], timeout: float = None) -> bool: ... @@ -46,6 +48,9 @@ class SelectElement(object): def cancel_by_loc(self, loc: Union[str, Tuple[str, str]], timeout: float = None) -> bool: ... + def cancel_by_option(self, + option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ... + def invert(self) -> None: ... def _by_loc(self, loc: Union[str, Tuple[str, str]], timeout: float = None, cancel: bool = False) -> bool: ... @@ -60,4 +65,7 @@ class SelectElement(object): def _index(self, condition: set, mode: str, timeout: float) -> bool: ... - def _dispatch_change(self) -> None: ... \ No newline at end of file + def _select_options(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]], + mode: str) -> None: ... + + def _dispatch_change(self) -> None: ... diff --git a/requirements.txt b/requirements.txt index dd6c6eb..ea3dad4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,6 @@ requests lxml cssselect DownloadKit>=2.0.0b0 -FlowViewer>=0.3.0 websocket-client click tldextract diff --git a/setup.py b/setup.py index 5bf2bc8..1ca634c 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="4.0.0b18", + version="4.0.0b19", author="g1879", author_email="g1879@qq.com", description="Python based web automation tool. It can control the browser and send and receive data packets.", @@ -23,7 +23,6 @@ setup( 'requests', 'cssselect', 'DownloadKit>=2.0.0b0', - 'FlowViewer>=0.3.0', 'websocket-client', 'click', 'tldextract',