From c07d90195d6a4930752adab8885b7909d525f66b Mon Sep 17 00:00:00 2001 From: g1879 Date: Sat, 27 Jan 2024 14:40:11 +0800 Subject: [PATCH] =?UTF-8?q?4.0.4(+)=20prop()=E6=94=B9=E6=88=90property()?= =?UTF-8?q?=EF=BC=8C=E5=8F=82=E6=95=B0=E6=94=B9=E4=B8=BAname=EF=BC=9B=20ge?= =?UTF-8?q?t=5Fsrc()=E6=94=B9=E4=B8=BAsrc()=EF=BC=9B=20get=5Fcookies()?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=94=B9=E6=88=90cookies()=EF=BC=9B=20?= =?UTF-8?q?=E5=88=A0=E9=99=A4cookies=E5=B1=9E=E6=80=A7=EF=BC=9B=20get=5Fse?= =?UTF-8?q?ssion=5Fstorage()=E3=80=81get=5Flocal=5Fstorage()=E6=94=B9?= =?UTF-8?q?=E6=88=90session=5Fstorage()=E3=80=81local=5Fstorage()=EF=BC=9B?= =?UTF-8?q?=20pageLoad=E6=94=B9=E6=88=90page=5Fload=EF=BC=9B=20set=5Fa=5Fh?= =?UTF-8?q?eader()=E3=80=81remove=5Fa=5Fheader()=E3=80=81set.header()?= =?UTF-8?q?=E3=80=81set.attr()=E7=9A=84=E5=8F=82=E6=95=B0=E6=94=B9?= =?UTF-8?q?=E4=B8=BAname=EF=BC=9B=20=E5=85=83=E7=B4=A0=E5=A2=9E=E5=8A=A0va?= =?UTF-8?q?lue=E5=B1=9E=E6=80=A7=E5=92=8Cset.value()=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=9B=20loc=5For=5Fele=E3=80=81loc=5For=5Fstr=E7=AD=89?= =?UTF-8?q?=E6=94=B9=E4=B8=BAlocator=EF=BC=9B=20=E6=8F=90=E9=AB=98?= =?UTF-8?q?=E6=88=AA=E5=9B=BEjpg=E6=A0=BC=E5=BC=8F=E7=94=BB=E8=B4=A8?= =?UTF-8?q?=EF=BC=9B=20=E4=BF=AE=E5=A4=8Ds=E6=A8=A1=E5=BC=8Ftimeout?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=A4=B1=E6=95=88=E9=97=AE=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8Dwait.has=5Frect()=E7=AD=89=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=9B=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=89=BE=E4=B8=8D=E5=88=B0=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E6=97=B6=E6=8A=A5ini=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/__init__.py | 2 +- DrissionPage/_base/base.py | 23 ++--- DrissionPage/_base/base.pyi | 52 ++++------- DrissionPage/_base/driver.py | 3 +- DrissionPage/_configs/chromium_options.py | 16 ++-- DrissionPage/_configs/chromium_options.pyi | 4 +- DrissionPage/_configs/session_options.py | 13 ++- DrissionPage/_configs/session_options.pyi | 4 +- DrissionPage/_elements/chromium_element.py | 69 +++++++------- DrissionPage/_elements/chromium_element.pyi | 92 +++++++++---------- DrissionPage/_elements/none_element.py | 3 +- DrissionPage/_elements/session_element.py | 20 ++--- DrissionPage/_elements/session_element.pyi | 45 +++++----- DrissionPage/_functions/browser.py | 21 ++--- DrissionPage/_functions/browser.pyi | 2 +- DrissionPage/_functions/tools.py | 8 +- DrissionPage/_functions/tools.pyi | 2 +- DrissionPage/_functions/web.py | 6 +- DrissionPage/_pages/chromium_base.py | 43 ++++++--- DrissionPage/_pages/chromium_base.pyi | 16 ++-- DrissionPage/_pages/chromium_frame.py | 99 +++++++++------------ DrissionPage/_pages/chromium_frame.pyi | 41 +++++---- DrissionPage/_pages/chromium_page.py | 12 +-- DrissionPage/_pages/chromium_page.pyi | 5 +- DrissionPage/_pages/chromium_tab.py | 29 +++--- DrissionPage/_pages/chromium_tab.pyi | 20 ++--- DrissionPage/_pages/session_page.py | 19 ++-- DrissionPage/_pages/session_page.pyi | 12 +-- DrissionPage/_pages/web_page.py | 23 ++--- DrissionPage/_pages/web_page.pyi | 21 ++--- DrissionPage/_units/clicker.pyi | 2 +- DrissionPage/_units/listener.py | 3 + DrissionPage/_units/rect.pyi | 2 +- DrissionPage/_units/selector.pyi | 4 +- DrissionPage/_units/setter.py | 33 ++++--- DrissionPage/_units/setter.pyi | 10 ++- DrissionPage/_units/states.py | 5 +- DrissionPage/_units/waiter.py | 9 +- DrissionPage/_units/waiter.pyi | 4 +- 39 files changed, 399 insertions(+), 398 deletions(-) diff --git a/DrissionPage/__init__.py b/DrissionPage/__init__.py index b64e503..6de9f07 100644 --- a/DrissionPage/__init__.py +++ b/DrissionPage/__init__.py @@ -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.3.5' +__version__ = '4.0.4' diff --git a/DrissionPage/_base/base.py b/DrissionPage/_base/base.py index 0156fbd..0339ef1 100644 --- a/DrissionPage/_base/base.py +++ b/DrissionPage/_base/base.py @@ -43,8 +43,7 @@ class BaseParser(object): def _ele(self, locator, timeout=None, index=1, raise_err=None, method=None): pass - @abstractmethod - def _find_elements(self, locator, timeout=None, index=1, raise_err=None): + def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None): pass @@ -89,10 +88,6 @@ class BaseElement(BaseParser): r.args = {'locator': locator, 'index': index} return r - @abstractmethod - def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None): - pass - class DrissionElement(BaseElement): """ChromiumElement 和 SessionElement的基类,但不是ShadowRoot的基类""" @@ -341,12 +336,15 @@ class DrissionElement(BaseElement): return @abstractmethod - def attr(self, attr: str): + def attr(self, name: str): return '' def _get_ele_path(self, mode): return '' + def _find_elements(self, locator, timeout=None, index=1, relative=False, raise_err=None): + pass + class BasePage(BaseParser): """页面类的基类""" @@ -380,11 +378,6 @@ class BasePage(BaseParser): """设置查找元素时等待的秒数""" self._timeout = second - @property - def cookies(self): - """返回cookies""" - return self.get_cookies(True) - @property def url_available(self): """返回当前访问的url有效性""" @@ -416,7 +409,7 @@ class BasePage(BaseParser): return @abstractmethod - def get_cookies(self, as_dict=False, all_info=False): + def cookies(self, as_dict=False, all_info=False): return {} @abstractmethod @@ -445,7 +438,3 @@ class BasePage(BaseParser): r.method = method r.args = {'locator': locator, 'index': index} return r - - @abstractmethod - def _find_elements(self, locator, timeout=None, index=1, raise_err=None): - pass diff --git a/DrissionPage/_base/base.pyi b/DrissionPage/_base/base.pyi index 2d4148d..6d7a54b 100644 --- a/DrissionPage/_base/base.pyi +++ b/DrissionPage/_base/base.pyi @@ -34,17 +34,17 @@ class BaseParser(object): def s_eles(self, locator: Union[Tuple[str, str], str]): ... def _ele(self, - locator, + locator: Union[Tuple[str, str], str], timeout: float = None, index: Optional[int] = 1, raise_err: bool = None, method: str = None): ... - @abstractmethod def _find_elements(self, - locator, + locator: Union[Tuple[str, str], str], timeout: float = None, index: Optional[int] = 1, + relative: bool = False, raise_err: bool = None): ... @@ -65,14 +65,6 @@ class BaseElement(BaseParser): raise_err: bool = None, method: str = None): ... - @abstractmethod - def _find_elements(self, - locator, - timeout: float = None, - index: Optional[int] = 1, - relative: bool = False, - raise_err: bool = None): ... - def parent(self, level_or_loc: Union[tuple, str, int] = 1): ... def prev(self, index: int = 1) -> None: ... @@ -109,57 +101,57 @@ class DrissionElement(BaseElement): index: int = 1) -> Union[DrissionElement, None]: ... def child(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... def prev(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... def next(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... def before(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... def after(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, ele_only: bool = True) -> Union[DrissionElement, str, NoneElement]: ... def children(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... def prevs(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... def nexts(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... def befores(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... def afters(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[DrissionElement, str]]: ... @@ -167,14 +159,14 @@ class DrissionElement(BaseElement): func: str, direction: str, brother: bool, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', index: int = 1, timeout: float = None, ele_only: bool = True) -> DrissionElement: ... def _get_relatives(self, index: int = None, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', direction: str = 'following', brother: bool = True, timeout: float = 0.5, @@ -191,7 +183,7 @@ class DrissionElement(BaseElement): def raw_text(self) -> str: ... @abstractmethod - def attr(self, attr: str) -> str: ... + def attr(self, name: str) -> str: ... def _get_ele_path(self, mode) -> str: ... @@ -217,9 +209,6 @@ class BasePage(BaseParser): @timeout.setter def timeout(self, second: float) -> None: ... - @property - def cookies(self) -> dict: ... - @property def url_available(self) -> bool: ... @@ -240,7 +229,7 @@ class BasePage(BaseParser): def user_agent(self) -> str: ... @abstractmethod - def get_cookies(self, as_dict: bool = False, all_info: bool = False) -> Union[list, dict]: ... + def cookies(self, as_dict: bool = False, all_info: bool = False) -> Union[list, dict]: ... @abstractmethod def get(self, url: str, show_errmsg: bool = False, retry: int = None, interval: float = None): ... @@ -251,10 +240,3 @@ class BasePage(BaseParser): index: Optional[int] = 1, raise_err: bool = None, method: str = None): ... - - @abstractmethod - def _find_elements(self, - locator, - timeout: float = None, - index: Optional[int] = 1, - raise_err: bool = None): ... diff --git a/DrissionPage/_base/driver.py b/DrissionPage/_base/driver.py index feb7e18..b442109 100644 --- a/DrissionPage/_base/driver.py +++ b/DrissionPage/_base/driver.py @@ -189,8 +189,9 @@ class Driver(object): timeout = kwargs.pop('_timeout', 30) result = self._send({'method': _method, 'params': kwargs}, timeout=timeout) if 'result' not in result and 'error' in result: + kwargs['_timeout'] = timeout return {'error': result['error']['message'], 'type': result.get('type', 'call_method_error'), - 'method': _method, 'args': kwargs, 'timeout': timeout} + 'method': _method, 'args': kwargs} else: return result['result'] diff --git a/DrissionPage/_configs/chromium_options.py b/DrissionPage/_configs/chromium_options.py index b224634..c5054af 100644 --- a/DrissionPage/_configs/chromium_options.py +++ b/DrissionPage/_configs/chromium_options.py @@ -26,7 +26,7 @@ class ChromiumOptions(object): if read_file is not False: ini_path = str(ini_path) if ini_path else None om = OptionsManager(ini_path) - self.ini_path = om.ini_path + self.ini_path = str(Path(om.ini_path).absolute()) options = om.chromium_options self._download_path = om.paths.get('download_path', None) or None @@ -56,7 +56,7 @@ class ChromiumOptions(object): timeouts = om.timeouts self._timeouts = {'base': timeouts['base'], - 'pageLoad': timeouts['page_load'], + 'page_load': timeouts['page_load'], 'script': timeouts['script']} self._auto_port = options.get('auto_port', False) @@ -75,7 +75,7 @@ class ChromiumOptions(object): self._extensions = [] self._prefs = {} self._flags = {} - self._timeouts = {'base': 10, 'pageLoad': 30, 'script': 30} + self._timeouts = {'base': 10, 'page_load': 30, 'script': 30} self._address = '127.0.0.1:9222' self._load_mode = 'normal' self._proxy = None @@ -278,18 +278,18 @@ class ChromiumOptions(object): self.clear_file_flags = True return self - def set_timeouts(self, base=None, pageLoad=None, script=None, implicit=None): + def set_timeouts(self, base=None, page_load=None, script=None, implicit=None): """设置超时时间,单位为秒 :param base: 默认超时时间 - :param pageLoad: 页面加载超时时间 + :param page_load: 页面加载超时时间 :param script: 脚本运行超时时间 :return: 当前对象 """ base = base if base is not None else implicit if base is not None: self._timeouts['base'] = base - if pageLoad is not None: - self._timeouts['pageLoad'] = pageLoad + if page_load is not None: + self._timeouts['page_load'] = page_load if script is not None: self._timeouts['script'] = script @@ -545,7 +545,7 @@ class ChromiumOptions(object): om.set_item('paths', 'tmp_path', self._tmp_path or '') # 设置timeout om.set_item('timeouts', 'base', self._timeouts['base']) - om.set_item('timeouts', 'page_load', self._timeouts['pageLoad']) + om.set_item('timeouts', 'page_load', self._timeouts['page_load']) om.set_item('timeouts', 'script', self._timeouts['script']) # 设置重试 om.set_item('others', 'retry_times', self.retry_times) diff --git a/DrissionPage/_configs/chromium_options.pyi b/DrissionPage/_configs/chromium_options.pyi index 0b7db3c..8dd05b2 100644 --- a/DrissionPage/_configs/chromium_options.pyi +++ b/DrissionPage/_configs/chromium_options.pyi @@ -109,7 +109,9 @@ class ChromiumOptions(object): def clear_flags_in_file(self) -> ChromiumOptions: ... - def set_timeouts(self, base: float = None, pageLoad: float = None, + def set_timeouts(self, + base: float = None, + page_load: float = None, script: float = None) -> ChromiumOptions: ... def set_user(self, user: str = 'Default') -> ChromiumOptions: ... diff --git a/DrissionPage/_configs/session_options.py b/DrissionPage/_configs/session_options.py index 532098a..135210a 100644 --- a/DrissionPage/_configs/session_options.py +++ b/DrissionPage/_configs/session_options.py @@ -171,28 +171,27 @@ class SessionOptions(object): self._headers = {key.lower(): headers[key] for key in headers} return self - def set_a_header(self, attr, value): + def set_a_header(self, name, value): """设置headers中一个项 - :param attr: 设置名称 + :param name: 设置名称 :param value: 设置值 :return: 返回当前对象 """ if self._headers is None: self._headers = {} - self._headers[attr.lower()] = value + self._headers[name.lower()] = value return self - def remove_a_header(self, attr): + def remove_a_header(self, name): """从headers中删除一个设置 - :param attr: 要删除的设置 + :param name: 要删除的设置 :return: 返回当前对象 """ if self._headers is None: return self - attr = attr.lower() - self._headers.pop(attr, None) + self._headers.pop(name.lower(), None) return self diff --git a/DrissionPage/_configs/session_options.pyi b/DrissionPage/_configs/session_options.pyi index cc1b4e9..532dd06 100644 --- a/DrissionPage/_configs/session_options.pyi +++ b/DrissionPage/_configs/session_options.pyi @@ -51,9 +51,9 @@ class SessionOptions(object): def set_headers(self, headers: Union[dict, None]) -> SessionOptions: ... - def set_a_header(self, attr: str, value: str) -> SessionOptions: ... + def set_a_header(self, name: str, value: str) -> SessionOptions: ... - def remove_a_header(self, attr: str) -> SessionOptions: ... + def remove_a_header(self, name: str) -> SessionOptions: ... @property def cookies(self) -> list: ... diff --git a/DrissionPage/_elements/chromium_element.py b/DrissionPage/_elements/chromium_element.py index 2b4e678..a50566b 100644 --- a/DrissionPage/_elements/chromium_element.py +++ b/DrissionPage/_elements/chromium_element.py @@ -78,8 +78,7 @@ class ChromiumElement(DrissionElement): self._doc_id = doc['objectId'] if doc else None def __repr__(self): - attrs = self.attrs - attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs] + attrs = [f"{k}='{v}'" for k, v in self.attrs.items()] return f'' def __call__(self, locator, index=1, timeout=None): @@ -128,10 +127,9 @@ class ChromiumElement(DrissionElement): @property def raw_text(self): """返回未格式化处理的元素内文本""" - return self.prop('innerText') + return self.property('innerText') # -----------------d模式独有属性------------------- - @property def set(self): """返回用于设置元素属性的对象""" @@ -206,6 +204,29 @@ class ChromiumElement(DrissionElement): return self._select + @property + def value(self): + return self.property('value') + + # -----即将废弃开始-------- + @property + def location(self): + """返回元素左上角的绝对坐标""" + return self.rect.location + + @property + def size(self): + """返回元素宽和高组成的元组""" + return self.rect.size + + def prop(self, prop): + return self.property(prop) + + def get_src(self, timeout=None, base64_to_bytes=True): + return self.src(timeout=timeout, base64_to_bytes=base64_to_bytes) + + # -----即将废弃结束-------- + def check(self, uncheck=False, by_js=False): """选中或取消选中当前元素 :param uncheck: 是否取消选中 @@ -345,10 +366,10 @@ class ChromiumElement(DrissionElement): if not link or link.lower().startswith(('javascript:', 'mailto:')): return link else: - return make_absolute_link(link, self.prop('baseURI')) + return make_absolute_link(link, self.property('baseURI')) elif attr == 'src': - return make_absolute_link(attrs.get('src', None), self.prop('baseURI')) + return make_absolute_link(attrs.get('src', None), self.property('baseURI')) elif attr == 'text': return self.text @@ -365,20 +386,20 @@ class ChromiumElement(DrissionElement): else: return attrs.get(attr, None) - def remove_attr(self, attr): + def remove_attr(self, name): """删除元素一个attribute属性 - :param attr: 属性名 + :param name: 属性名 :return: None """ - self.run_js(f'this.removeAttribute("{attr}");') + self.run_js(f'this.removeAttribute("{name}");') - def prop(self, prop): + def property(self, name): """获取一个property属性值 - :param prop: 属性名 + :param name: 属性名 :return: 属性值文本 """ try: - value = self.run_js(f'return this.{prop};') + value = self.run_js(f'return this.{name};') return format_html(value) if isinstance(value, str) else value except: return None @@ -467,7 +488,7 @@ class ChromiumElement(DrissionElement): pseudo_ele = f', "{pseudo_ele}"' if pseudo_ele.startswith(':') else f', "::{pseudo_ele}"' return self.run_js(f'return window.getComputedStyle(this{pseudo_ele}).getPropertyValue("{style}");') - def get_src(self, timeout=None, base64_to_bytes=True): + def src(self, timeout=None, base64_to_bytes=True): """返回元素src资源,base64的可转为bytes返回,其它返回str :param timeout: 等待资源加载的超时时间(秒) :param base64_to_bytes: 为True时,如果是base64数据,转换为bytes格式 @@ -501,7 +522,7 @@ class ChromiumElement(DrissionElement): break else: - src = self.prop('currentSrc') + src = self.property('currentSrc') if not src: continue @@ -533,7 +554,7 @@ class ChromiumElement(DrissionElement): :param timeout: 等待资源加载的超时时间(秒) :return: 返回保存路径 """ - data = self.get_src(timeout=timeout) + data = self.src(timeout=timeout) if not data: raise NoResourceError @@ -543,7 +564,7 @@ class ChromiumElement(DrissionElement): if src.lower().startswith('data:image'): r = search(r'data:image/(.*?);base64,', src) name = f'img.{r.group(1)}' if r else None - name = name or basename(self.prop('currentSrc')) + name = name or basename(self.property('currentSrc')) path = get_usable_path(f'{path}{sep}{name}').absolute() write_type = 'wb' if isinstance(data, bytes) else 'w' @@ -595,7 +616,7 @@ class ChromiumElement(DrissionElement): self.clear(True) if isinstance(vals, (list, tuple)): vals = ''.join([str(i) for i in vals]) - self.set.prop('value', str(vals)) + self.set.property('value', str(vals)) self.run_js('this.dispatchEvent(new Event("change", {bubbles: true}));') return @@ -751,18 +772,6 @@ class ChromiumElement(DrissionElement): files = [str(Path(i).absolute()) for i in files] self.page.run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=self._backend_id) - # -------------即将废弃------------- - - @property - def location(self): - """返回元素左上角的绝对坐标""" - return self.rect.location - - @property - def size(self): - """返回元素宽和高组成的元组""" - return self.rect.size - class ShadowRoot(BaseElement): """ShadowRoot是用于处理ShadowRoot的类,使用方法和ChromiumElement基本一致""" @@ -1421,7 +1430,7 @@ def run_js(page_or_ele, script, as_expr, timeout, args=None): else: raise ElementLostError('原来获取到的元素对象已不在页面内。') - if res is None and page.states.has_alert: # 存在alert的情况 + if res is None and page.states.has_alert: return None exceptionDetails = res.get('exceptionDetails') diff --git a/DrissionPage/_elements/chromium_element.pyi b/DrissionPage/_elements/chromium_element.pyi index 1403ae1..69f7bb4 100644 --- a/DrissionPage/_elements/chromium_element.pyi +++ b/DrissionPage/_elements/chromium_element.pyi @@ -8,7 +8,6 @@ from pathlib import Path from typing import Union, Tuple, List, Any, Literal, Optional -from .none_element import NoneElement from .._base.base import DrissionElement, BaseElement from .._elements.session_element import SessionElement from .._pages.chromium_base import ChromiumBase @@ -50,7 +49,7 @@ class ChromiumElement(DrissionElement): def __call__(self, locator: Union[Tuple[str, str], str], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... + timeout: float = None) -> ChromiumElement: ... def __eq__(self, other: ChromiumElement) -> bool: ... @@ -73,7 +72,6 @@ class ChromiumElement(DrissionElement): def raw_text(self) -> str: ... # -----------------d模式独有属性------------------- - @property def set(self) -> ChromiumElementSetter: ... @@ -100,60 +98,60 @@ class ChromiumElement(DrissionElement): def parent(self, level_or_loc: Union[tuple, str, int] = 1, - index: int = 1) -> Union[ChromiumElement, NoneElement]: ... + index: int = 1) -> ChromiumElement: ... def child(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def prev(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def next(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def before(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def after(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def children(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def prevs(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def nexts(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def befores(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def afters(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... @@ -163,13 +161,16 @@ class ChromiumElement(DrissionElement): @property def select(self) -> SelectElement: ... + @property + def value(self) -> None: ... + def check(self, uncheck: bool = False, by_js: bool = False) -> None: ... - def attr(self, attr: str) -> Union[str, None]: ... + def attr(self, name: str) -> Union[str, None]: ... - def remove_attr(self, attr: str) -> None: ... + def remove_attr(self, name: str) -> None: ... - def prop(self, prop: str) -> Union[str, int, None]: ... + def property(self, name: str) -> Union[str, int, None]: ... def run_js(self, script: str, *args, as_expr: bool = False, timeout: float = None) -> Any: ... @@ -178,7 +179,7 @@ class ChromiumElement(DrissionElement): def ele(self, locator: Union[Tuple[str, str], str], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... + timeout: float = None) -> ChromiumElement: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -186,7 +187,7 @@ class ChromiumElement(DrissionElement): def s_ele(self, locator: Union[Tuple[str, str], str] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, locator: Union[Tuple[str, str], str] = None) -> List[SessionElement]: ... @@ -195,12 +196,12 @@ class ChromiumElement(DrissionElement): timeout: float = None, index: Optional[int] = 1, relative: bool = False, - raise_err: bool = False) -> Union[ChromiumElement, ChromiumFrame, NoneElement, + raise_err: bool = False) -> Union[ChromiumElement, ChromiumFrame, List[Union[ChromiumElement, ChromiumFrame]]]: ... def style(self, style: str, pseudo_ele: str = '') -> str: ... - def get_src(self, timeout: float = None, base64_to_bytes: bool = True) -> Union[bytes, str, None]: ... + def src(self, timeout: float = None, base64_to_bytes: bool = True) -> Union[bytes, str, None]: ... def save(self, path: [str, bool] = None, name: str = None, timeout: float = None) -> str: ... @@ -273,33 +274,33 @@ class ShadowRoot(BaseElement): def parent(self, level_or_loc: Union[str, int] = 1, index: int = 1) -> ChromiumElement: ... def child(self, - locator: Union[tuple, str] = '', - index: int = 1) -> Union[ChromiumElement, NoneElement]: ... + locator: Union[Tuple[str, str], str] = '', + index: int = 1) -> ChromiumElement: ... def next(self, - locator: Union[tuple, str] = '', - index: int = 1) -> Union[ChromiumElement, NoneElement]: ... + locator: Union[Tuple[str, str], str] = '', + index: int = 1) -> ChromiumElement: ... def before(self, - locator: Union[tuple, str] = '', - index: int = 1) -> Union[ChromiumElement, NoneElement]: ... + locator: Union[Tuple[str, str], str] = '', + index: int = 1) -> ChromiumElement: ... def after(self, - locator: Union[tuple, str] = '', - index: int = 1) -> Union[ChromiumElement, NoneElement]: ... + locator: Union[Tuple[str, str], str] = '', + index: int = 1) -> ChromiumElement: ... - def children(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ... + def children(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ... - def nexts(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ... + def nexts(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ... - def befores(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ... + def befores(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ... - def afters(self, locator: Union[tuple, str] = '') -> List[ChromiumElement]: ... + def afters(self, locator: Union[Tuple[str, str], str] = '') -> List[ChromiumElement]: ... def ele(self, locator: Union[Tuple[str, str], str], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... + timeout: float = None) -> ChromiumElement: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -307,7 +308,7 @@ class ShadowRoot(BaseElement): def s_ele(self, locator: Union[Tuple[str, str], str] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ... @@ -316,7 +317,7 @@ class ShadowRoot(BaseElement): timeout: float = None, index: Optional[int] = 1, relative: bool = False, - raise_err: bool = None) -> Union[ChromiumElement, ChromiumFrame, NoneElement, str, + raise_err: bool = None) -> Union[ChromiumElement, ChromiumFrame, str, List[Union[ChromiumElement, ChromiumFrame, str]]]: ... def _get_node_id(self, obj_id: str) -> int: ... @@ -330,28 +331,27 @@ def find_in_chromium_ele(ele: ChromiumElement, loc: Union[str, Tuple[str, str]], index: Optional[int] = 1, timeout: float = None, - relative: bool = True) -> Union[ChromiumElement, NoneElement, List[ChromiumElement]]: ... + relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement]]: ... def find_by_xpath(ele: ChromiumElement, xpath: str, index: Optional[int], timeout: float, - relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ... + relative: bool = True) -> Union[ChromiumElement, List[ChromiumElement]]: ... def find_by_css(ele: ChromiumElement, selector: str, index: Optional[int], - timeout: float) -> Union[ChromiumElement, List[ChromiumElement], NoneElement]: ... + timeout: float) -> Union[ChromiumElement, List[ChromiumElement],]: ... def make_chromium_eles(page: Union[ChromiumBase, ChromiumPage, WebPage, ChromiumTab, ChromiumFrame], _ids: Union[tuple, list, str, int], index: Optional[int] = 1, is_obj_id: bool = True - ) -> Union[ChromiumElement, ChromiumFrame, NoneElement, -List[Union[ChromiumElement, ChromiumFrame]]]: ... + ) -> Union[ChromiumElement, ChromiumFrame, List[Union[ChromiumElement, ChromiumFrame]]]: ... def make_js_for_find_ele_by_xpath(xpath: str, type_txt: str, node_txt: str) -> str: ... diff --git a/DrissionPage/_elements/none_element.py b/DrissionPage/_elements/none_element.py index fac5415..15502f3 100644 --- a/DrissionPage/_elements/none_element.py +++ b/DrissionPage/_elements/none_element.py @@ -18,6 +18,7 @@ class NoneElement(object): self._none_ele_return_value = False self.method = method self.args = args + self._get = None def __call__(self, *args, **kwargs): if not self._none_ele_return_value: @@ -33,7 +34,7 @@ class NoneElement(object): return self else: if item in ('size', 'link', 'css_path', 'xpath', 'comments', 'texts', 'tag', 'html', 'inner_html', - 'attrs', 'text', 'raw_text'): + 'attrs', 'text', 'raw_text', 'value', 'attr', 'style', 'src', 'property'): return self._none_ele_value else: raise ElementNotFoundError(None, self.method, self.args) diff --git a/DrissionPage/_elements/session_element.py b/DrissionPage/_elements/session_element.py index 8b6173d..208c8e4 100644 --- a/DrissionPage/_elements/session_element.py +++ b/DrissionPage/_elements/session_element.py @@ -34,7 +34,7 @@ class SessionElement(DrissionElement): return self._inner_ele def __repr__(self): - attrs = [f"{attr}='{self.attrs[attr]}'" for attr in self.attrs] + attrs = [f"{k}='{v}'" for k, v in self.attrs.items()] return f'' def __call__(self, locator, timeout=None): @@ -188,13 +188,13 @@ class SessionElement(DrissionElement): """ return super().afters(locator, timeout, ele_only=ele_only) - def attr(self, attr): + def attr(self, name): """返回attribute属性值 - :param attr: 属性名 + :param name: 属性名 :return: 属性值文本,没有该属性返回None """ # 获取href属性时返回绝对url - if attr == 'href': + if name == 'href': link = self.inner_ele.get('href') # 若为链接为None、js或邮件,直接返回 if not link or link.lower().startswith(('javascript:', 'mailto:')): @@ -203,23 +203,23 @@ class SessionElement(DrissionElement): else: # 其它情况直接返回绝对url return make_absolute_link(link, self.page.url) - elif attr == 'src': + elif name == 'src': return make_absolute_link(self.inner_ele.get('src'), self.page.url) - elif attr == 'text': + elif name == 'text': return self.text - elif attr == 'innerText': + elif name == 'innerText': return self.raw_text - elif attr in ('html', 'outerHTML'): + elif name in ('html', 'outerHTML'): return self.html - elif attr == 'innerHTML': + elif name == 'innerHTML': return self.inner_html else: - return self.inner_ele.get(attr) + return self.inner_ele.get(name) def ele(self, locator, index=1, timeout=None): """返回当前元素下级符合条件的一个元素、属性或节点文本 diff --git a/DrissionPage/_elements/session_element.pyi b/DrissionPage/_elements/session_element.pyi index 66d6156..563beae 100644 --- a/DrissionPage/_elements/session_element.pyi +++ b/DrissionPage/_elements/session_element.pyi @@ -9,7 +9,6 @@ from typing import Union, List, Tuple, Optional from lxml.html import HtmlElement -from .none_element import NoneElement from .._base.base import DrissionElement, BaseElement from .._elements.chromium_element import ChromiumElement from .._pages.chromium_base import ChromiumBase @@ -31,7 +30,7 @@ class SessionElement(DrissionElement): def __call__(self, locator: Union[Tuple[str, str], str], index: int = 1, - timeout: float = None) -> Union[SessionElement, NoneElement]: ... + timeout: float = None) -> SessionElement: ... def __eq__(self, other: SessionElement) -> bool: ... @@ -55,69 +54,69 @@ class SessionElement(DrissionElement): def parent(self, level_or_loc: Union[tuple, str, int] = 1, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def child(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[SessionElement, str]: ... def prev(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[SessionElement, str]: ... def next(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[SessionElement, str]: ... def before(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[SessionElement, str]: ... def after(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[SessionElement, str, NoneElement]: ... + ele_only: bool = True) -> Union[SessionElement, str]: ... def children(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[SessionElement, str]]: ... def prevs(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[SessionElement, str]]: ... def nexts(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[SessionElement, str]]: ... def befores(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[SessionElement, str]]: ... def afters(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[SessionElement, str]]: ... - def attr(self, attr: str) -> Optional[str]: ... + def attr(self, name: str) -> Optional[str]: ... def ele(self, locator: Union[Tuple[str, str], str], index: int = 1, - timeout: float = None) -> Union[SessionElement, NoneElement]: ... + timeout: float = None) -> SessionElement: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -125,7 +124,7 @@ class SessionElement(DrissionElement): def s_ele(self, locator: Union[Tuple[str, str], str] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ... @@ -134,7 +133,7 @@ class SessionElement(DrissionElement): timeout: float = None, index: Optional[int] = 1, relative: bool = False, - raise_err: bool = None) -> Union[SessionElement, NoneElement, List[SessionElement]]: ... + raise_err: bool = None) -> Union[SessionElement, List[SessionElement]]: ... def _get_ele_path(self, mode: str) -> str: ... @@ -142,4 +141,4 @@ class SessionElement(DrissionElement): def make_session_ele(html_or_ele: Union[str, SessionElement, SessionPage, ChromiumElement, BaseElement, ChromiumFrame, ChromiumBase], loc: Union[str, Tuple[str, str]] = None, - index: Optional[int] = 1) -> Union[SessionElement, NoneElement, List[SessionElement]]: ... + index: Optional[int] = 1) -> Union[SessionElement, List[SessionElement]]: ... diff --git a/DrissionPage/_functions/browser.py b/DrissionPage/_functions/browser.py index 54b1b5a..ad8803e 100644 --- a/DrissionPage/_functions/browser.py +++ b/DrissionPage/_functions/browser.py @@ -26,7 +26,7 @@ def connect_browser(option): :return: 返回是否接管的浏览器 """ address = option.address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://') - chrome_path = option.browser_path + browser_path = option.browser_path ip, port = address.split(':') if ip != '127.0.0.1' or port_is_using(ip, port) or option.is_existing_only: @@ -43,16 +43,16 @@ def connect_browser(option): set_prefs(option) set_flags(option) try: - _run_browser(port, chrome_path, args) + _run_browser(port, browser_path, args) # 传入的路径找不到,主动在ini文件、注册表、系统变量中找 except FileNotFoundError: - chrome_path = get_chrome_path() + browser_path = get_chrome_path(option.ini_path) - if not chrome_path: + if not browser_path: raise FileNotFoundError('无法找到浏览器可执行文件路径,请手动配置。') - _run_browser(port, chrome_path, args) + _run_browser(port, browser_path, args) test_connect(ip, port) return False @@ -219,7 +219,7 @@ def test_connect(ip, port, timeout=30): def _run_browser(port, path: str, args) -> Popen: - """创建chrome进程 + """创建浏览器进程 :param port: 端口号 :param path: 浏览器路径 :param args: 启动参数 @@ -282,12 +282,13 @@ def _remove_arg_from_dict(target_dict: dict, arg: str) -> None: pass -def get_chrome_path(): +def get_chrome_path(ini_path): """从ini文件或系统变量中获取chrome可执行文件的路径""" # -----------从ini文件中获取-------------- - path = OptionsManager().chromium_options.get('browser_path', None) - if path and Path(path).is_file(): - return str(path) + if ini_path: + path = OptionsManager(ini_path).chromium_options.get('browser_path', None) + if path and Path(path).is_file(): + return str(path) # -----------使用which获取----------- from shutil import which diff --git a/DrissionPage/_functions/browser.pyi b/DrissionPage/_functions/browser.pyi index 6285a34..8815ab4 100644 --- a/DrissionPage/_functions/browser.pyi +++ b/DrissionPage/_functions/browser.pyi @@ -25,4 +25,4 @@ def set_flags(opt: ChromiumOptions) -> None: ... def test_connect(ip: str, port: Union[int, str], timeout: float = 30) -> None: ... -def get_chrome_path() -> Union[str, None]: ... +def get_chrome_path(ini_path: str) -> Union[str, None]: ... diff --git a/DrissionPage/_functions/tools.py b/DrissionPage/_functions/tools.py index 4ae6f5a..ee4ba25 100644 --- a/DrissionPage/_functions/tools.py +++ b/DrissionPage/_functions/tools.py @@ -112,7 +112,7 @@ def show_or_hide_browser(page, hide=True): pid = page.process_id if not pid: return None - hds = get_chrome_hwnds_from_pid(pid, page.title) + hds = get_hwnds_from_pid(pid, page.title) sw = SW_HIDE if hide else SW_SHOW for hd in hds: ShowWindow(hd, sw) @@ -141,7 +141,7 @@ def get_browser_progress_id(progress, address): return txt.split(' ')[-1] -def get_chrome_hwnds_from_pid(pid, title): +def get_hwnds_from_pid(pid, title): """通过PID查询句柄ID :param pid: 进程id :param title: 窗口标题 @@ -240,11 +240,11 @@ def raise_error(result, ignore=None): elif error == 'Given expression does not evaluate to a function': r = JavaScriptError(f'传入的js无法解析成函数:\n{result["args"]["functionDeclaration"]}') elif error.endswith("' wasn't found"): - r = RuntimeError(f'你的浏览器可能太旧。\nmethod:{result["method"]}\nargs:{result["args"]}') + r = RuntimeError(f'你的浏览器可能太旧。\n方法:{result["method"]}\n参数:{result["args"]}') elif result['type'] in ('call_method_error', 'timeout'): from DrissionPage import __version__ from time import process_time - txt = f'\n错误:{result["error"]}\nmethod:{result["method"]}\nargs:{result["args"]}\n' \ + txt = f'\n错误:{result["error"]}\n方法:{result["method"]}\n参数:{result["args"]}\n' \ f'版本:{__version__}\n运行时间:{process_time()}\n出现这个错误可能意味着程序有bug,请把错误信息和重现方法' \ '告知作者,谢谢。\n报告网站:https://gitee.com/g1879/DrissionPage/issues' r = TimeoutError(txt) if result['type'] == 'timeout' else CDPError(txt) diff --git a/DrissionPage/_functions/tools.pyi b/DrissionPage/_functions/tools.pyi index dd9d507..f6e13f5 100644 --- a/DrissionPage/_functions/tools.pyi +++ b/DrissionPage/_functions/tools.pyi @@ -36,7 +36,7 @@ def show_or_hide_browser(page: ChromiumPage, hide: bool = True) -> None: ... def get_browser_progress_id(progress: Union[popen, None], address: str) -> Union[str, None]: ... -def get_chrome_hwnds_from_pid(pid: Union[str, int], title: str) -> list: ... +def get_hwnds_from_pid(pid: Union[str, int], title: str) -> list: ... def wait_until(function: callable, kwargs: dict = None, timeout: float = 10): ... diff --git a/DrissionPage/_functions/web.py b/DrissionPage/_functions/web.py index c34c778..fcc5baa 100644 --- a/DrissionPage/_functions/web.py +++ b/DrissionPage/_functions/web.py @@ -161,8 +161,8 @@ def is_js_func(func): func = func.strip() if (func.startswith('function') or func.startswith('async ')) and func.endswith('}'): return True - elif '=>' in func: - return True + # elif '=>' in func: + # return True return False @@ -361,3 +361,5 @@ def get_blob(page, url, as_bytes=True): if as_bytes: from base64 import b64decode return b64decode(result.split(',', 1)[-1]) + else: + return result diff --git a/DrissionPage/_pages/chromium_base.py b/DrissionPage/_pages/chromium_base.py index 489c19d..eb0aa96 100644 --- a/DrissionPage/_pages/chromium_base.py +++ b/DrissionPage/_pages/chromium_base.py @@ -474,8 +474,8 @@ class ChromiumBase(BasePage): show_errmsg=show_errmsg, timeout=timeout) return self._url_available - def get_cookies(self, as_dict=False, all_domains=False, all_info=False): - """获取cookies信息 + def cookies(self, as_dict=False, all_domains=False, all_info=False): + """返回cookies信息 :param as_dict: 为True时返回由{name: value}键值对组成的dict,为True时返回list且all_info无效 :param all_domains: 是否返回所有域的cookies :param all_info: 是否返回所有信息,为False时只返回name、value、domain @@ -722,8 +722,8 @@ class ChromiumBase(BasePage): frames = self._ele(locator, timeout=timeout, index=None, raise_err=False) return [i for i in frames if i._type == 'ChromiumFrame'] - def get_session_storage(self, item=None): - """获取sessionStorage信息,不设置item则获取全部 + def session_storage(self, item=None): + """返回sessionStorage信息,不设置item则获取全部 :param item: 要获取的项,不设置则返回全部 :return: sessionStorage一个或所有项内容 """ @@ -743,8 +743,8 @@ class ChromiumBase(BasePage): ''' return {i['key']: i['val'] for i in self.run_js_loaded(js)} - def get_local_storage(self, item=None): - """获取localStorage信息,不设置item则获取全部 + def local_storage(self, item=None): + """返回localStorage信息,不设置item则获取全部 :param item: 要获取的项目,不设置则返回全部 :return: localStorage一个或所有项内容 """ @@ -930,7 +930,11 @@ class ChromiumBase(BasePage): :param interval: 重试间隔 :return: 重试次数和间隔组成的tuple """ - self._url = quote(url, safe='-_.~!*\'"();:@&=+$,/\\?#[]%') or 'chrome://newtab/' + p = Path(url) + if p.exists(): + self._url = str(p.absolute()) + else: + self._url = quote(url, safe='-_.~!*\'"();:@&=+$,/\\?#[]%') or 'chrome://newtab/' retry = retry if retry is not None else self.retry_times interval = interval if interval is not None else self.retry_interval return retry, interval @@ -1033,11 +1037,12 @@ class ChromiumBase(BasePage): pic_type = path.suffix.lower() pic_type = 'jpeg' if pic_type == '.jpg' else pic_type[1:] - width, height = self.rect.size if full_page: + width, height = self.rect.size + if width == 0 or height == 0: + raise RuntimeError('页面大小为0,请尝试等待页面加载完成。') vp = {'x': 0, 'y': 0, 'width': width, 'height': height, 'scale': 1} - png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type, - captureBeyondViewport=True, clip=vp)['data'] + args = {'format': pic_type, 'captureBeyondViewport': True, 'clip': vp} else: if left_top and right_bottom: x, y = left_top @@ -1051,11 +1056,14 @@ class ChromiumBase(BasePage): x += 10 vp = {'x': x, 'y': y, 'width': w, 'height': h, 'scale': 1} - png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type, - captureBeyondViewport=v, clip=vp)['data'] + args = {'format': pic_type, 'captureBeyondViewport': v, 'clip': vp} else: - png = self.run_cdp_loaded('Page.captureScreenshot', format=pic_type)['data'] + args = {'format': pic_type} + + if pic_type == 'jpeg': + args['quality'] = 100 + png = self.run_cdp_loaded('Page.captureScreenshot', **args)['data'] if as_base64: return png @@ -1095,6 +1103,15 @@ class ChromiumBase(BasePage): """返回页面总宽高,格式:(宽, 高)""" return self.rect.size + def get_session_storage(self, item=None): + return self.session_storage(item) + + def get_local_storage(self, item=None): + return self.local_storage(item) + + def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info) + class Timeout(object): """用于保存d模式timeout信息的类""" diff --git a/DrissionPage/_pages/chromium_base.pyi b/DrissionPage/_pages/chromium_base.pyi index dca5bc0..0b51500 100644 --- a/DrissionPage/_pages/chromium_base.pyi +++ b/DrissionPage/_pages/chromium_base.pyi @@ -13,7 +13,6 @@ from .._base.base import BasePage from .._base.browser import Browser from .._base.driver import Driver from .._elements.chromium_element import ChromiumElement -from .._elements.none_element import NoneElement from .._elements.session_element import SessionElement from .._pages.chromium_frame import ChromiumFrame from .._pages.chromium_page import ChromiumPage @@ -97,7 +96,7 @@ class ChromiumBase(BasePage): def __call__(self, locator: Union[Tuple[str, str], str, ChromiumElement], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... + timeout: float = None) -> ChromiumElement: ... @property def _js_ready_state(self) -> str: ... @@ -177,13 +176,12 @@ class ChromiumBase(BasePage): def get(self, url: str, show_errmsg: bool = False, retry: int = None, interval: float = None, timeout: float = None) -> Union[None, bool]: ... - def get_cookies(self, as_dict: bool = False, all_domains: bool = False, - all_info: bool = False) -> Union[list, dict]: ... + def cookies(self, as_dict: bool = False, all_domains: bool = False, all_info: bool = False) -> Union[list, dict]: ... def ele(self, locator: Union[Tuple[str, str], str, ChromiumElement, ChromiumFrame], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... + timeout: float = None) -> ChromiumElement: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -191,7 +189,7 @@ class ChromiumBase(BasePage): def s_ele(self, locator: Union[Tuple[str, str], str] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ... @@ -201,7 +199,7 @@ class ChromiumBase(BasePage): index: Optional[int] = 1, relative: bool = False, raise_err: bool = None) \ - -> Union[ChromiumElement, ChromiumFrame, NoneElement, List[Union[ChromiumElement, ChromiumFrame]]]: ... + -> Union[ChromiumElement, ChromiumFrame, List[Union[ChromiumElement, ChromiumFrame]]]: ... def refresh(self, ignore_cache: bool = False) -> None: ... @@ -223,9 +221,9 @@ class ChromiumBase(BasePage): def run_cdp_loaded(self, cmd: str, **cmd_args) -> dict: ... - def get_session_storage(self, item: str = None) -> Union[str, dict, None]: ... + def session_storage(self, item: str = None) -> Union[str, dict, None]: ... - def get_local_storage(self, item: str = None) -> Union[str, dict, None]: ... + def local_storage(self, item: str = None) -> Union[str, dict, None]: ... def add_init_js(self, script: str) -> str: ... diff --git a/DrissionPage/_pages/chromium_frame.py b/DrissionPage/_pages/chromium_frame.py index dd8946d..5544fe4 100644 --- a/DrissionPage/_pages/chromium_frame.py +++ b/DrissionPage/_pages/chromium_frame.py @@ -78,8 +78,7 @@ class ChromiumFrame(ChromiumBase): return self._frame_id == getattr(other, '_frame_id', None) def __repr__(self): - attrs = self._frame_ele.attrs - attrs = [f"{attr}='{attrs[attr]}'" for attr in attrs] + attrs = [f"{k}='{v}'" for k, v in self._frame_ele.attrs.items()] return f'' def _d_set_runtime_settings(self): @@ -146,19 +145,6 @@ class ChromiumFrame(ChromiumBase): if timeout <= 0: timeout = .5 self._wait_loaded(timeout) - # while perf_counter() < end_time: - # try: - # obj_id = super().run_js('document;', as_expr=True)['objectId'] - # self.doc_ele = ChromiumElement(self, obj_id=obj_id) - # break - # except Exception as e: - # sleep(.1) - # if self._debug: - # print(f'获取doc失败,重试 {e}') - # else: - # raise GetDocumentError - - # self.driver._debug = d_debug self._is_loading = False self._reloading = False @@ -208,7 +194,6 @@ class ChromiumFrame(ChromiumBase): self._reload() # ----------挂件---------- - @property def scroll(self): """返回用于滚动的对象""" @@ -252,7 +237,7 @@ class ChromiumFrame(ChromiumBase): self._listener = FrameListener(self) return self._listener - # ----------挂件---------- + # ----------挂件结束---------- @property def _obj_id(self): @@ -305,11 +290,6 @@ class ChromiumFrame(ChromiumBase): r = self._ele('t:title', raise_err=False) return r.text if r else None - @property - def cookies(self): - """以dict格式返回cookies""" - return super().cookies if self._is_diff_domain else self.doc_ele.run_js('return this.cookie;') - @property def attrs(self): """返回frame元素所有attribute属性""" @@ -356,23 +336,57 @@ class ChromiumFrame(ChromiumBase): except: return None + # ----------------即将废弃----------------- + @property + def is_alive(self): + """返回是否仍可用""" + return self.states.is_alive + + @property + def page_size(self): + """返回frame内页面尺寸,格式:(宽,, 高)""" + return self.rect.size + + @property + def size(self): + """返回frame元素大小""" + return self.frame_ele.rect.size + + @property + def location(self): + """返回frame元素左上角的绝对坐标""" + return self.frame_ele.rect.location + + @property + def locations(self): + """返回用于获取元素位置的对象""" + return self.frame_ele.rect + # ----------------即将废弃结束----------------- + def refresh(self): """刷新frame页面""" self.doc_ele.run_js('this.location.reload();') - def attr(self, attr): - """返回frame元素attribute属性值 - :param attr: 属性名 + def property(self, name): + """返回frame元素一个property属性值 + :param name: 属性名 :return: 属性值文本,没有该属性返回None """ - return self.frame_ele.attr(attr) + return self.frame_ele.property(name) - def remove_attr(self, attr): + def attr(self, name): + """返回frame元素一个attribute属性值 + :param name: 属性名 + :return: 属性值文本,没有该属性返回None + """ + return self.frame_ele.attr(name) + + def remove_attr(self, name): """删除frame元素attribute属性 - :param attr: 属性名 + :param name: 属性名 :return: None """ - self.frame_ele.remove_attr(attr) + self.frame_ele.remove_attr(name) def run_js(self, script, *args, as_expr=False, timeout=None): """运行javascript代码 @@ -580,30 +594,3 @@ class ChromiumFrame(ChromiumBase): def _is_inner_frame(self): """返回当前frame是否同域""" return self._frame_id in str(self._target_page.run_cdp('Page.getFrameTree')['frameTree']) - - # ----------------即将废弃----------------- - - @property - def is_alive(self): - """返回是否仍可用""" - return self.states.is_alive - - @property - def page_size(self): - """返回frame内页面尺寸,格式:(宽,, 高)""" - return self.rect.size - - @property - def size(self): - """返回frame元素大小""" - return self.frame_ele.rect.size - - @property - def location(self): - """返回frame元素左上角的绝对坐标""" - return self.frame_ele.rect.location - - @property - def locations(self): - """返回用于获取元素位置的对象""" - return self.frame_ele.rect diff --git a/DrissionPage/_pages/chromium_frame.pyi b/DrissionPage/_pages/chromium_frame.pyi index 15eaa6c..a98db83 100644 --- a/DrissionPage/_pages/chromium_frame.pyi +++ b/DrissionPage/_pages/chromium_frame.pyi @@ -13,7 +13,6 @@ from .chromium_page import ChromiumPage from .chromium_tab import ChromiumTab from .web_page import WebPage from .._elements.chromium_element import ChromiumElement -from .._elements.none_element import NoneElement from .._units.listener import FrameListener from .._units.rect import FrameRect from .._units.scroller import FrameScroller @@ -32,6 +31,7 @@ class ChromiumFrame(ChromiumBase): self._target_page: ChromiumBase = ... self.tab: ChromiumTab = ... self._tab_id: str = ... + self._set: ChromiumFrameSetter = ... self._frame_ele: ChromiumElement = ... self._backend_id: int = ... self._doc_ele: ChromiumElement = ... @@ -45,7 +45,7 @@ class ChromiumFrame(ChromiumBase): def __call__(self, locator: Union[Tuple[str, str], str], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, NoneElement]: ... + timeout: float = None) -> ChromiumElement: ... def __eq__(self, other: ChromiumFrame) -> bool: ... @@ -86,9 +86,6 @@ class ChromiumFrame(ChromiumBase): @property def title(self) -> str: ... - @property - def cookies(self) -> dict: ... - @property def attrs(self) -> dict: ... @@ -133,9 +130,11 @@ class ChromiumFrame(ChromiumBase): def refresh(self) -> None: ... - def attr(self, attr: str) -> Union[str, None]: ... + def property(self, name: str) -> Union[str, None]: ... - def remove_attr(self, attr: str) -> None: ... + def attr(self, name: str) -> Union[str, None]: ... + + def remove_attr(self, name: str) -> None: ... def run_js(self, script: str, @@ -144,50 +143,50 @@ class ChromiumFrame(ChromiumBase): timeout: float = None) -> Any: ... def parent(self, - level_or_loc: Union[tuple, str, int] = 1, - index: int = 1) -> Union[ChromiumElement, NoneElement]: ... + level_or_loc: Union[Tuple[str, str], str, int] = 1, + index: int = 1) -> ChromiumElement: ... def prev(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = 0, - ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def next(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = 0, - ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def before(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def after(self, - locator: Union[tuple, str, int] = '', + locator: Union[Tuple[str, str], str, int] = '', index: int = 1, timeout: float = None, - ele_only: bool = True) -> Union[ChromiumElement, NoneElement, str]: ... + ele_only: bool = True) -> Union[ChromiumElement, str]: ... def prevs(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = 0, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def nexts(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = 0, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def befores(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... def afters(self, - locator: Union[tuple, str] = '', + locator: Union[Tuple[str, str], str] = '', timeout: float = None, ele_only: bool = True) -> List[Union[ChromiumElement, str]]: ... diff --git a/DrissionPage/_pages/chromium_page.py b/DrissionPage/_pages/chromium_page.py index 554552d..a57f531 100644 --- a/DrissionPage/_pages/chromium_page.py +++ b/DrissionPage/_pages/chromium_page.py @@ -24,7 +24,7 @@ from ..errors import BrowserConnectError class ChromiumPage(ChromiumBase): """用于管理浏览器的类""" - PAGES = {} + _PAGES = {} def __new__(cls, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None): """ @@ -35,8 +35,8 @@ class ChromiumPage(ChromiumBase): addr_or_opts = addr_or_opts or addr_driver_opts opt = handle_options(addr_or_opts) is_exist, browser_id = run_browser(opt) - if browser_id in cls.PAGES: - r = cls.PAGES[browser_id] + if browser_id in cls._PAGES: + r = cls._PAGES[browser_id] while not hasattr(r, '_frame_id'): sleep(.1) return r @@ -45,7 +45,7 @@ class ChromiumPage(ChromiumBase): r._is_exist = is_exist r._browser_id = browser_id r.address = opt.address - cls.PAGES[browser_id] = r + cls._PAGES[browser_id] = r return r def __init__(self, addr_or_opts=None, tab_id=None, timeout=None, addr_driver_opts=None): @@ -79,7 +79,7 @@ class ChromiumPage(ChromiumBase): def _d_set_runtime_settings(self): """设置运行时用到的属性""" - self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['pageLoad'], + self._timeouts = Timeout(self, page_load=self._chromium_options.timeouts['page_load'], script=self._chromium_options.timeouts['script'], base=self._chromium_options.timeouts['base']) if self._chromium_options.timeouts['base'] is not None: @@ -255,7 +255,7 @@ class ChromiumPage(ChromiumBase): def _on_disconnect(self): """浏览器退出时执行""" - ChromiumPage.PAGES.pop(self._browser_id, None) + ChromiumPage._PAGES.pop(self._browser_id, None) def __repr__(self): return f'' diff --git a/DrissionPage/_pages/chromium_page.pyi b/DrissionPage/_pages/chromium_page.pyi index 7e9065f..8b74035 100644 --- a/DrissionPage/_pages/chromium_page.pyi +++ b/DrissionPage/_pages/chromium_page.pyi @@ -19,7 +19,7 @@ from .._units.waiter import PageWaiter class ChromiumPage(ChromiumBase): - PAGES: dict = ... + _PAGES: dict = ... def __new__(cls, addr_or_opts: Union[str, int, ChromiumOptions] = None, @@ -55,9 +55,6 @@ class ChromiumPage(ChromiumBase): @property def wait(self) -> PageWaiter: ... - @property - def main_tab(self) -> str: ... - @property def latest_tab(self) -> str: ... diff --git a/DrissionPage/_pages/chromium_tab.py b/DrissionPage/_pages/chromium_tab.py index 25d0ec1..6baeb61 100644 --- a/DrissionPage/_pages/chromium_tab.py +++ b/DrissionPage/_pages/chromium_tab.py @@ -20,20 +20,20 @@ from .._units.waiter import TabWaiter class ChromiumTab(ChromiumBase): """实现浏览器标签页的类""" - TABS = {} + _TABS = {} def __new__(cls, page, tab_id): """ :param page: ChromiumPage对象 :param tab_id: 要控制的标签页id """ - if Settings.singleton_tab_obj and tab_id in cls.TABS: - r = cls.TABS[tab_id] + if Settings.singleton_tab_obj and tab_id in cls._TABS: + r = cls._TABS[tab_id] while not hasattr(r, '_frame_id'): sleep(.1) return r r = object.__new__(cls) - cls.TABS[tab_id] = r + cls._TABS[tab_id] = r return r def __init__(self, page, tab_id): @@ -96,7 +96,7 @@ class ChromiumTab(ChromiumBase): return f'' def _on_disconnect(self): - ChromiumTab.TABS.pop(self.tab_id, None) + ChromiumTab._TABS.pop(self.tab_id, None) class WebPageTab(SessionPage, ChromiumTab, BasePage): @@ -188,11 +188,6 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage): """返回当前模式,'s'或'd' """ return self._mode - @property - def cookies(self): - """以dict方式返回cookies""" - return super().cookies - @property def user_agent(self): """返回user agent""" @@ -357,15 +352,15 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage): user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] self._headers.update({"User-Agent": user_agent}) - set_session_cookies(self.session, super(SessionPage, self).get_cookies()) + set_session_cookies(self.session, super(SessionPage, self).cookies()) def cookies_to_browser(self): """把session对象的cookies复制到浏览器""" if not self._has_driver: return - set_browser_cookies(self, super().get_cookies()) + set_browser_cookies(self, super().cookies()) - def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + def cookies(self, as_dict=False, all_domains=False, all_info=False): """返回cookies :param as_dict: 是否以字典方式返回 :param all_domains: 是否返回所有域的cookies @@ -373,9 +368,9 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage): :return: cookies信息 """ if self._mode == 's': - return super().get_cookies(as_dict, all_domains, all_info) + return super().cookies(as_dict, all_domains, all_info) elif self._mode == 'd': - return super(SessionPage, self).get_cookies(as_dict, all_domains, all_info) + return super(SessionPage, self).cookies(as_dict, all_domains, all_info) def close(self): """关闭当前标签页""" @@ -400,3 +395,7 @@ class WebPageTab(SessionPage, ChromiumTab, BasePage): def __repr__(self): return f'' + + # --------即将废弃------- + def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info) \ No newline at end of file diff --git a/DrissionPage/_pages/chromium_tab.pyi b/DrissionPage/_pages/chromium_tab.pyi index e4b55b8..2a5f6a5 100644 --- a/DrissionPage/_pages/chromium_tab.pyi +++ b/DrissionPage/_pages/chromium_tab.pyi @@ -6,7 +6,6 @@ @License : BSD 3-Clause. """ from pathlib import Path -from threading import Lock from typing import Union, Tuple, Any, List, Optional from requests import Session, Response @@ -18,7 +17,6 @@ from .session_page import SessionPage from .web_page import WebPage from .._base.browser import Browser from .._elements.chromium_element import ChromiumElement -from .._elements.none_element import NoneElement from .._elements.session_element import SessionElement from .._units.rect import TabRect from .._units.setter import TabSetter, WebPageTabSetter @@ -26,8 +24,7 @@ from .._units.waiter import TabWaiter class ChromiumTab(ChromiumBase): - TABS: dict = ... - LOCK: Lock = ... + _TABS: dict = ... def __new__(cls, page: ChromiumPage, tab_id: str): ... @@ -82,7 +79,7 @@ class WebPageTab(SessionPage, ChromiumTab): def __call__(self, locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... + timeout: float = None) -> Union[ChromiumElement, SessionElement]: ... @property def page(self) -> WebPage: ... @@ -111,9 +108,6 @@ class WebPageTab(SessionPage, ChromiumTab): @property def mode(self) -> str: ... - @property - def cookies(self) -> dict: ... - @property def user_agent(self) -> str: ... @@ -152,7 +146,7 @@ class WebPageTab(SessionPage, ChromiumTab): def ele(self, locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... + timeout: float = None) -> Union[ChromiumElement, SessionElement]: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -160,7 +154,7 @@ class WebPageTab(SessionPage, ChromiumTab): def s_ele(self, locator: Union[Tuple[str, str], str] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ... @@ -170,8 +164,8 @@ class WebPageTab(SessionPage, ChromiumTab): def cookies_to_browser(self) -> None: ... - def get_cookies(self, as_dict: bool = False, all_domains: bool = False, - all_info: bool = False) -> Union[dict, list]: ... + def cookies(self, as_dict: bool = False, all_domains: bool = False, + all_info: bool = False) -> Union[dict, list]: ... def close(self) -> None: ... @@ -205,5 +199,5 @@ class WebPageTab(SessionPage, ChromiumTab): index: Optional[int] = 1, relative: bool = False, raise_err: bool = None) \ - -> Union[ChromiumElement, SessionElement, ChromiumFrame, NoneElement, List[SessionElement], List[ + -> Union[ChromiumElement, SessionElement, ChromiumFrame, List[SessionElement], List[ Union[ChromiumElement, ChromiumFrame]]]: ... diff --git a/DrissionPage/_pages/session_page.py b/DrissionPage/_pages/session_page.py index 38177b4..7c13ad2 100644 --- a/DrissionPage/_pages/session_page.py +++ b/DrissionPage/_pages/session_page.py @@ -47,8 +47,11 @@ class SessionPage(BasePage): :param session_or_options: Session、SessionOptions对象 :return: None """ - if not session_or_options or isinstance(session_or_options, SessionOptions): - self._session_options = session_or_options or SessionOptions(session_or_options) + if not session_or_options: + self._session_options = SessionOptions(session_or_options) + + elif isinstance(session_or_options, SessionOptions): + self._session_options = session_or_options elif isinstance(session_or_options, Session): self._session_options = SessionOptions() @@ -208,7 +211,7 @@ class SessionPage(BasePage): """ return self._ele(locator, index=None) - def _find_elements(self, locator, timeout=None, index=1, raise_err=None): + def _find_elements(self, locator, timeout=None, index=1, relative=True, raise_err=None): """返回页面中符合条件的元素、属性或节点文本,默认返回第一个 :param locator: 元素的定位信息,可以是元素对象,loc元组,或查询字符串 :param timeout: 不起实际作用,用于和父类对应 @@ -218,7 +221,7 @@ class SessionPage(BasePage): """ return locator if isinstance(locator, SessionElement) else make_session_ele(self, locator, index=index) - def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + def cookies(self, as_dict=False, all_domains=False, all_info=False): """返回cookies :param as_dict: 是否以字典方式返回,False则以list返回 :param all_domains: 是否返回所有域的cookies @@ -310,7 +313,7 @@ class SessionPage(BasePage): parsed_url = urlparse(url) hostname = parsed_url.hostname scheme = parsed_url.scheme - if not check_headers(kwargs, self._headers, 'Referer'): + if not check_headers(kwargs['headers'], self._headers, 'Referer'): kwargs['headers']['Referer'] = self.url if self.url else f'{scheme}://{hostname}' if 'Host' not in kwargs['headers']: kwargs['headers']['Host'] = hostname @@ -364,10 +367,14 @@ class SessionPage(BasePage): def __repr__(self): return f'' + # ---------即将废弃--------- + def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info) + def check_headers(kwargs, headers, arg): """检查kwargs或headers中是否有arg所示属性""" - return arg in kwargs['headers'] or arg in headers + return arg in kwargs or arg in headers def set_charset(response): diff --git a/DrissionPage/_pages/session_page.pyi b/DrissionPage/_pages/session_page.pyi index 15f9b24..90673e2 100644 --- a/DrissionPage/_pages/session_page.pyi +++ b/DrissionPage/_pages/session_page.pyi @@ -13,7 +13,6 @@ from requests.structures import CaseInsensitiveDict from .._base.base import BasePage from .._configs.session_options import SessionOptions -from .._elements.none_element import NoneElement from .._elements.session_element import SessionElement from .._units.setter import SessionPageSetter @@ -43,7 +42,7 @@ class SessionPage(BasePage): def __call__(self, locator: Union[Tuple[str, str], str, SessionElement], index: int = 1, - timeout: float = None) -> Union[SessionElement, NoneElement]: ... + timeout: float = None) -> SessionElement: ... # -----------------共有属性和方法------------------- @property @@ -93,7 +92,7 @@ class SessionPage(BasePage): def ele(self, locator: Union[Tuple[str, str], str, SessionElement], index: int = 1, - timeout: float = None) -> Union[SessionElement, NoneElement]: ... + timeout: float = None) -> SessionElement: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -101,7 +100,7 @@ class SessionPage(BasePage): def s_ele(self, locator: Union[Tuple[str, str], str, SessionElement] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, loc: Union[Tuple[str, str], str]) -> List[SessionElement]: ... @@ -109,10 +108,11 @@ class SessionPage(BasePage): locator: Union[Tuple[str, str], str, SessionElement], timeout: float = None, index: Optional[int] = 1, + relative: bool = True, raise_err: bool = None) \ - -> Union[SessionElement, NoneElement, List[SessionElement]]: ... + -> Union[SessionElement, List[SessionElement]]: ... - def get_cookies(self, + def cookies(self, as_dict: bool = False, all_domains: bool = False, all_info: bool = False) -> Union[dict, list]: ... diff --git a/DrissionPage/_pages/web_page.py b/DrissionPage/_pages/web_page.py index 8fa0b15..dd0b843 100644 --- a/DrissionPage/_pages/web_page.py +++ b/DrissionPage/_pages/web_page.py @@ -126,11 +126,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage): """返回当前模式,'s'或'd' """ return self._mode - @property - def cookies(self): - """以dict方式返回cookies""" - return super().cookies - @property def user_agent(self): """返回user agent""" @@ -281,7 +276,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage): if go: url = super(SessionPage, self).url if url.startswith('http'): - self.get(url) + r = self.get(url) + if not r: + raise ConnectionError('s模式访问失败,请设置go=False,自行构造连接参数进行访问。') def cookies_to_session(self, copy_user_agent=True): """把driver对象的cookies复制到session对象 @@ -295,15 +292,15 @@ class WebPage(SessionPage, ChromiumPage, BasePage): user_agent = self.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value'] self._headers.update({"User-Agent": user_agent}) - set_session_cookies(self.session, super(SessionPage, self).get_cookies()) + set_session_cookies(self.session, super(SessionPage, self).cookies()) def cookies_to_browser(self): """把session对象的cookies复制到浏览器""" if not self._has_driver: return - set_browser_cookies(self, super().get_cookies()) + set_browser_cookies(self, super().cookies()) - def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + def cookies(self, as_dict=False, all_domains=False, all_info=False): """返回cookies :param as_dict: 是否以字典方式返回,False以list形式返回 :param all_domains: 是否返回所有域的cookies @@ -311,9 +308,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage): :return: cookies信息 """ if self._mode == 's': - return super().get_cookies(as_dict, all_domains, all_info) + return super().cookies(as_dict, all_domains, all_info) elif self._mode == 'd': - return super(SessionPage, self).get_cookies(as_dict, all_domains, all_info) + return super(SessionPage, self).cookies(as_dict, all_domains, all_info) def get_tab(self, id_or_num=None): """获取一个标签页对象 @@ -408,3 +405,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage): def __repr__(self): return f'' + + # -------即将废弃-------- + def get_cookies(self, as_dict=False, all_domains=False, all_info=False): + return self.cookies(as_dict=as_dict, all_domains=all_domains, all_info=all_info) diff --git a/DrissionPage/_pages/web_page.pyi b/DrissionPage/_pages/web_page.pyi index 517dfd3..0f11253 100644 --- a/DrissionPage/_pages/web_page.pyi +++ b/DrissionPage/_pages/web_page.pyi @@ -18,7 +18,6 @@ from .._base.driver import Driver from .._configs.chromium_options import ChromiumOptions from .._configs.session_options import SessionOptions from .._elements.chromium_element import ChromiumElement -from .._elements.none_element import NoneElement from .._elements.session_element import SessionElement from .._units.setter import WebPageSetter @@ -31,6 +30,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage): chromium_options: Union[ChromiumOptions, bool] = None, session_or_options: Union[Session, SessionOptions, bool] = None) -> None: self._mode: str = ... + self._set: WebPageSetter = ... self._has_driver: bool = ... self._has_session: bool = ... self._session_options: Union[SessionOptions, None] = ... @@ -39,7 +39,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage): def __call__(self, locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... + timeout: float = None) -> Union[ChromiumElement, SessionElement]: ... # -----------------共有属性和方法------------------- @property @@ -66,9 +66,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage): @property def mode(self) -> str: ... - @property - def cookies(self) -> dict: ... - @property def user_agent(self) -> str: ... @@ -107,7 +104,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage): def ele(self, locator: Union[Tuple[str, str], str, ChromiumElement, SessionElement], index: int = 1, - timeout: float = None) -> Union[ChromiumElement, SessionElement, NoneElement]: ... + timeout: float = None) -> Union[ChromiumElement, SessionElement]: ... def eles(self, locator: Union[Tuple[str, str], str], @@ -115,7 +112,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage): def s_ele(self, locator: Union[Tuple[str, str], str] = None, - index: int = 1) -> Union[SessionElement, NoneElement]: ... + index: int = 1) -> SessionElement: ... def s_eles(self, locator: Union[Tuple[str, str], str]) -> List[SessionElement]: ... @@ -125,10 +122,10 @@ class WebPage(SessionPage, ChromiumPage, BasePage): def cookies_to_browser(self) -> None: ... - def get_cookies(self, - as_dict: bool = False, - all_domains: bool = False, - all_info: bool = False) -> Union[dict, list]: ... + def cookies(self, + as_dict: bool = False, + all_domains: bool = False, + all_info: bool = False) -> Union[dict, list]: ... def get_tab(self, id_or_num: Union[str, WebPageTab, int] = None) -> WebPageTab: ... @@ -174,7 +171,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage): index: Optional[int] = 1, relative: bool = False, raise_err: bool = None) \ - -> Union[ChromiumElement, SessionElement, ChromiumFrame, NoneElement, List[SessionElement], + -> Union[ChromiumElement, SessionElement, ChromiumFrame, List[SessionElement], List[Union[ChromiumElement, ChromiumFrame]]]: ... def _set_start_options(self, diff --git a/DrissionPage/_units/clicker.pyi b/DrissionPage/_units/clicker.pyi index 895f762..5ac0a16 100644 --- a/DrissionPage/_units/clicker.pyi +++ b/DrissionPage/_units/clicker.pyi @@ -5,7 +5,7 @@ @Copyright: (c) 2024 by g1879, Inc. All Rights Reserved. @License : BSD 3-Clause. """ -from typing import Union, Optional +from typing import Optional from .._elements.chromium_element import ChromiumElement diff --git a/DrissionPage/_units/listener.py b/DrissionPage/_units/listener.py index 80ee15a..80ebe03 100644 --- a/DrissionPage/_units/listener.py +++ b/DrissionPage/_units/listener.py @@ -100,6 +100,9 @@ class Listener(object): Manifest, SignedExchange, Ping, CSPViolationReport, Preflight, Other :return: None """ + if targets is not None: + if is_regex is None: + is_regex = False if targets or is_regex is not None or method or res_type: self.set_targets(targets, is_regex, method, res_type) self.clear() diff --git a/DrissionPage/_units/rect.pyi b/DrissionPage/_units/rect.pyi index 2e442ce..62fadc1 100644 --- a/DrissionPage/_units/rect.pyi +++ b/DrissionPage/_units/rect.pyi @@ -6,7 +6,7 @@ @License : BSD 3-Clause. """ -from typing import Tuple, Union, List +from typing import Tuple, Union from .._elements.chromium_element import ChromiumElement from .._pages.chromium_base import ChromiumBase diff --git a/DrissionPage/_units/selector.pyi b/DrissionPage/_units/selector.pyi index 06f0553..87877ad 100644 --- a/DrissionPage/_units/selector.pyi +++ b/DrissionPage/_units/selector.pyi @@ -38,7 +38,7 @@ class SelectElement(object): def by_index(self, index: Union[int, list, tuple], timeout: float = None) -> bool: ... - def by_locator(self, locator: Union[str, Tuple[str, str]], timeout: float = None) -> bool: ... + def by_locator(self, locator: Union[Tuple[str, str], str], timeout: float = None) -> bool: ... def by_option(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ... @@ -48,7 +48,7 @@ class SelectElement(object): def cancel_by_index(self, index: Union[int, list, tuple], timeout: float = None) -> bool: ... - def cancel_by_locator(self, locator: Union[str, Tuple[str, str]], timeout: float = None) -> bool: ... + def cancel_by_locator(self, locator: Union[Tuple[str, str], str], timeout: float = None) -> bool: ... def cancel_by_option(self, option: Union[ChromiumElement, List[ChromiumElement], Tuple[ChromiumElement]]) -> None: ... diff --git a/DrissionPage/_units/setter.py b/DrissionPage/_units/setter.py index 2e10d4f..48301c3 100644 --- a/DrissionPage/_units/setter.py +++ b/DrissionPage/_units/setter.py @@ -293,13 +293,13 @@ class SessionPageSetter(BasePageSetter): """ self._page._headers = CaseInsensitiveDict(headers) - def header(self, attr, value): + def header(self, name, value): """设置headers中一个项 - :param attr: 设置名称 + :param name: 设置名称 :param value: 设置值 :return: None """ - self._page._headers[attr] = value + self._page._headers[name] = value def user_agent(self, ua): """设置user agent @@ -450,39 +450,46 @@ class ChromiumElementSetter(object): """ self._ele = ele - def attr(self, attr, value): + def attr(self, name, value): """设置元素attribute属性 - :param attr: 属性名 + :param name: 属性名 :param value: 属性值 :return: None """ - self._ele.page.run_cdp('DOM.setAttributeValue', nodeId=self._ele._node_id, name=attr, value=str(value)) + self._ele.page.run_cdp('DOM.setAttributeValue', nodeId=self._ele._node_id, name=name, value=str(value)) - def prop(self, prop, value): + def property(self, name, value): """设置元素property属性 - :param prop: 属性名 + :param name: 属性名 :param value: 属性值 :return: None """ value = value.replace('"', r'\"') - self._ele.run_js(f'this.{prop}="{value}";') + self._ele.run_js(f'this.{name}="{value}";') def innerHTML(self, html): """设置元素innerHTML :param html: html文本 :return: None """ - self.prop('innerHTML', html) + self.property('innerHTML', html) + + def value(self, value): + """设置元素value值 + :param value: value值 + :return: None + """ + self.property('value', value) class ChromiumFrameSetter(ChromiumBaseSetter): - def attr(self, attr, value): + def attr(self, name, value): """设置frame元素attribute属性 - :param attr: 属性名 + :param name: 属性名 :param value: 属性值 :return: None """ - self._page.frame_ele.set.attr(attr, value) + self._page.frame_ele.set.attr(name, value) class LoadMode(object): diff --git a/DrissionPage/_units/setter.pyi b/DrissionPage/_units/setter.pyi index a5ece0b..901e084 100644 --- a/DrissionPage/_units/setter.pyi +++ b/DrissionPage/_units/setter.pyi @@ -113,7 +113,7 @@ class SessionPageSetter(BasePageSetter): def headers(self, headers: dict) -> None: ... - def header(self, attr: str, value: str) -> None: ... + def header(self, name: str, value: str) -> None: ... def user_agent(self, ua: str) -> None: ... @@ -168,17 +168,19 @@ class ChromiumElementSetter(object): def __init__(self, ele: ChromiumElement): self._ele: ChromiumElement = ... - def attr(self, attr: str, value: str) -> None: ... + def attr(self, name: str, value: str) -> None: ... - def prop(self, prop: str, value: str) -> None: ... + def property(self, name: str, value: str) -> None: ... def innerHTML(self, html: str) -> None: ... + def value(self, value: str) -> None: ... + class ChromiumFrameSetter(ChromiumBaseSetter): _page: ChromiumFrame = ... - def attr(self, attr: str, value: str) -> None: ... + def attr(self, name: str, value: str) -> None: ... class LoadMode(object): diff --git a/DrissionPage/_units/states.py b/DrissionPage/_units/states.py index bdf99cc..e6bc267 100644 --- a/DrissionPage/_units/states.py +++ b/DrissionPage/_units/states.py @@ -29,8 +29,9 @@ class ElementStates(object): @property def is_displayed(self): """返回元素是否显示""" - return not (self._ele.style('visibility') == 'hidden' or self._ele.run_js('return this.offsetParent === null;') - or self._ele.style('display') == 'none' or self._ele.prop('hidden')) + return not (self._ele.style('visibility') == 'hidden' or + self._ele.run_js('return this.offsetParent === null;') + or self._ele.style('display') == 'none' or self._ele.property('hidden')) @property def is_enabled(self): diff --git a/DrissionPage/_units/waiter.py b/DrissionPage/_units/waiter.py index 09867c9..5398a1b 100644 --- a/DrissionPage/_units/waiter.py +++ b/DrissionPage/_units/waiter.py @@ -119,6 +119,8 @@ class BaseWaiter(object): :param cancel_it: 是否取消该任务 :return: 成功返回任务对象,失败返回False """ + if not self._driver.browser._dl_mgr._running: + raise RuntimeError('使用下载管理功能前需显式设置下载路径(使用set.download_path()方法、配置对象或ini文件均可)。') self._driver.browser._dl_mgr.set_flag(self._driver.tab_id, False if cancel_it else True) if timeout is None: timeout = self._driver.timeout @@ -232,6 +234,8 @@ class TabWaiter(BaseWaiter): :param cancel_if_timeout: 超时时是否取消剩余任务 :return: 是否等待成功 """ + if not self._driver.browser._dl_mgr._running: + raise RuntimeError('使用下载管理功能前需显式设置下载路径(使用set.download_path()方法、配置对象或ini文件均可)。') if not timeout: while self._driver.browser._dl_mgr.get_tab_missions(self._driver.tab_id): sleep(.5) @@ -290,6 +294,8 @@ class PageWaiter(TabWaiter): :param cancel_if_timeout: 超时时是否取消剩余任务 :return: 是否等待成功 """ + if not self._driver.browser._dl_mgr._running: + raise RuntimeError('使用下载管理功能前需显式设置下载路径(使用set.download_path()方法、配置对象或ini文件均可)。') if not timeout: while self._driver.browser._dl_mgr._missions: sleep(.5) @@ -458,7 +464,8 @@ class ElementWaiter(object): timeout = self._page.timeout end_time = perf_counter() + timeout while perf_counter() < end_time: - if self._ele.states.__getattribute__(attr) == mode: + a = self._ele.states.__getattribute__(attr) + if (a and mode) or (not a and not mode): return True sleep(.05) diff --git a/DrissionPage/_units/waiter.pyi b/DrissionPage/_units/waiter.pyi index c5eb2a9..92ed44b 100644 --- a/DrissionPage/_units/waiter.pyi +++ b/DrissionPage/_units/waiter.pyi @@ -5,7 +5,7 @@ @Copyright: (c) 2024 by g1879, Inc. All Rights Reserved. @License : BSD 3-Clause. """ -from typing import Union +from typing import Union, Tuple from .downloader import DownloadMission from .._elements.chromium_element import ChromiumElement @@ -34,7 +34,7 @@ class BaseWaiter(object): raise_err: bool = None) -> bool: ... def ele_loaded(self, - locator: Union[str, tuple], + locator: Union[Tuple[str, str], str], timeout: float = None, raise_err: bool = None) -> Union[bool, ChromiumElement]: ...