3.2.1默认下载方式改为用浏览器;wait增加download_begin()方法;common文件夹改名为commons

This commit is contained in:
g1879 2023-02-23 10:55:46 +08:00
parent 28330ac49c
commit a0ffd4707a
36 changed files with 112 additions and 86 deletions

View File

@ -14,7 +14,7 @@ from .configs.session_options import SessionOptions
# 常用工具
from .action_chains import ActionChains
from .common.keys import Keys
from .commons.keys import Keys
# 旧版页面类和启动配置类
try:

View File

@ -5,8 +5,8 @@
"""
from time import sleep
from .common.keys import modifierBit, keyDescriptionForString
from .common.web import location_in_viewport
from .commons.keys import modifierBit, keyDescriptionForString
from .commons.web import location_in_viewport
class ActionChains:

View File

@ -7,9 +7,9 @@ from abc import abstractmethod
from re import sub
from urllib.parse import quote
from .common.constants import Settings, NoneElement
from .common.locator import get_loc
from .common.web import format_html
from .commons.constants import Settings, NoneElement
from .commons.locator import get_loc
from .commons.web import format_html
from .errors import ElementNotFoundError

View File

@ -6,7 +6,7 @@
from abc import abstractmethod
from typing import Union, Tuple, List
from .common.constants import NoneElement
from .commons.constants import NoneElement
class BaseParser(object):

View File

@ -14,10 +14,10 @@ from .base import BasePage
from .chromium_driver import ChromiumDriver
from .chromium_element import ChromiumWaiter, ChromiumScroll, ChromiumElement, run_js, make_chromium_ele, \
ChromiumElementWaiter
from .common.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement
from .common.locator import get_loc
from .common.tools import get_usable_path
from .common.web import cookies_to_tuple
from .commons.constants import HANDLE_ALERT_METHOD, ERROR, NoneElement
from .commons.locator import get_loc
from .commons.tools import get_usable_path
from .commons.web import cookies_to_tuple
from .errors import ContextLossError, ElementLossError, AlertExistsError, CallMethodError, TabClosedError, \
NoRectError
from .session_element import make_session_ele
@ -312,7 +312,7 @@ class ChromiumBase(BasePage):
def wait(self):
"""返回用于等待的对象"""
if self._wait is None:
self._wait = ChromiumPageWaiter(self)
self._wait = ChromiumBaseWaiter(self)
return self._wait
@property
@ -901,7 +901,7 @@ class ChromiumBaseSetter(object):
self._page.run_cdp('Network.setExtraHTTPHeaders', headers=headers)
class ChromiumPageWaiter(ChromiumWaiter):
class ChromiumBaseWaiter(ChromiumWaiter):
def __init__(self, page):
"""
:param page: 所属页面对象

View File

@ -10,7 +10,7 @@ from DataRecorder import Recorder
from requests import Session
from requests.cookies import RequestsCookieJar
from .common.constants import NoneElement
from .commons.constants import NoneElement
from .base import BasePage
from .chromium_driver import ChromiumDriver
from .chromium_element import ChromiumElement, ChromiumScroll, ChromiumWaiter
@ -38,7 +38,7 @@ class ChromiumBase(BasePage):
self._debug: bool = ...
self._debug_recorder: Recorder = ...
self._upload_list: list = ...
self._wait: ChromiumPageWaiter = ...
self._wait: ChromiumBaseWaiter = ...
self._set: ChromiumBaseSetter = ...
def _connect_browser(self, tab_id: str = None) -> None: ...
@ -113,7 +113,7 @@ class ChromiumBase(BasePage):
def upload_list(self) -> list: ...
@property
def wait(self) -> ChromiumPageWaiter: ...
def wait(self) -> ChromiumBaseWaiter: ...
@property
def set(self) -> ChromiumBaseSetter: ...
@ -193,7 +193,7 @@ class ChromiumBase(BasePage):
timeout: float = None) -> Union[bool, None]: ...
class ChromiumPageWaiter(ChromiumWaiter):
class ChromiumBaseWaiter(ChromiumWaiter):
def __init__(self, page: ChromiumBase):
self._driver: ChromiumBase = ...

View File

@ -10,20 +10,20 @@ from time import perf_counter, sleep
from warnings import warn
from .base import DrissionElement, BaseElement
from .common.constants import FRAME_ELEMENT, NoneElement, Settings
from .common.keys import keys_to_typing, keyDescriptionForString, keyDefinitions
from .common.locator import get_loc
from .common.web import make_absolute_link, get_ele_txt, format_html, is_js_func, location_in_viewport, offset_scroll
from .commons.constants import FRAME_ELEMENT, NoneElement, Settings
from .commons.keys import keys_to_typing, keyDescriptionForString, keyDefinitions
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
from .session_element import make_session_ele
class ChromiumElement(DrissionElement):
"""ChromePage页面对象中的元素对象"""
"""控制浏览器元素的对象"""
def __init__(self, page, node_id=None, obj_id=None, backend_id=None):
"""初始化,node_id、obj_id和backend_id必须至少传入一个
"""node_id、obj_id和backend_id必须至少传入一个
:param page: 元素所在ChromePage页面对象
:param node_id: cdp中的node id
:param obj_id: js中的object id
@ -66,7 +66,6 @@ class ChromiumElement(DrissionElement):
def __call__(self, loc_or_str, timeout=None):
"""在内部查找元素
ele2 = ele1('@id=ele_id')
:param loc_or_str: 元素的定位信息可以是loc元组或查询字符串
:param timeout: 超时时间
:return: ChromiumElement对象或属性文本
@ -97,7 +96,7 @@ class ChromiumElement(DrissionElement):
try:
attrs = self.page.run_cdp('DOM.getAttributes', nodeId=self._node_id)['attributes']
return {attrs[i]: attrs[i + 1] for i in range(0, len(attrs), 2)}
except CallMethodError:
except CallMethodError: # 文档根元素不能调用此方法
return {}
@property
@ -118,7 +117,7 @@ class ChromiumElement(DrissionElement):
@property
def size(self):
"""返回元素宽和高"""
"""返回元素宽和高组成的元组"""
model = self.page.run_cdp('DOM.getBoxModel', backendNodeId=self._backend_id)['model']
return model['height'], model['width']
@ -277,7 +276,7 @@ class ChromiumElement(DrissionElement):
return super().afters(filter_loc, timeout)
def attr(self, attr):
"""返回attribute属性值
"""返回一个attribute属性值
:param attr: 属性名
:return: 属性值文本没有该属性返回None
"""
@ -308,14 +307,14 @@ class ChromiumElement(DrissionElement):
return attrs.get(attr, None)
def remove_attr(self, attr):
"""删除元素attribute属性
"""删除元素一个attribute属性
:param attr: 属性名
:return: None
"""
self.run_js(f'this.removeAttribute("{attr}");')
def prop(self, prop):
"""获取property属性值
"""获取一个property属性值
:param prop: 属性名
:return: 属性值文本
"""
@ -328,7 +327,7 @@ class ChromiumElement(DrissionElement):
return format_html(i['value']['value'])
def run_js(self, script, *args, as_expr=False):
"""行javascript代码
"""对本元素执行javascript代码
:param script: js文本
:param args: 参数按顺序在js文本中对应argument[0]argument[1]...
:param as_expr: 是否作为表达式运行为True时args无效
@ -337,7 +336,7 @@ class ChromiumElement(DrissionElement):
return run_js(self, script, as_expr, self.page.timeouts.script, args)
def run_async_js(self, script, *args, as_expr=False):
"""以异步方式执行js代码
"""以异步方式对本元素执行javascript代码
:param script: js文本
:param args: 参数按顺序在js文本中对应argument[0]argument[1]...
:param as_expr: 是否作为表达式运行为True时args无效
@ -363,7 +362,7 @@ class ChromiumElement(DrissionElement):
return self._ele(loc_or_str, timeout=timeout, single=False)
def s_ele(self, loc_or_str=None):
"""查找第一个符合条件的元素以SessionElement形式返回,处理复杂页面时效率很高
"""查找第一个符合条件的元素以SessionElement形式返回
:param loc_or_str: 元素的定位信息可以是loc元组或查询字符串
:return: SessionElement对象或属性文本
"""
@ -372,7 +371,7 @@ class ChromiumElement(DrissionElement):
return make_session_ele(self, loc_or_str)
def s_eles(self, loc_or_str=None):
"""查找所有符合条件的元素以SessionElement列表形式返回
"""查找所有符合条件的元素以SessionElement列表形式返回
:param loc_or_str: 定位符
:return: SessionElement或属性文本组成的列表
"""
@ -450,7 +449,7 @@ class ChromiumElement(DrissionElement):
f.write(data)
def get_screenshot(self, path=None, as_bytes=None):
"""对当前元素截图
"""对当前元素截图,可保存到文件,或以字节方式返回
:param path: 完整路径后缀可选 'jpg','jpeg','png','webp'
:param as_bytes: 是否已字节形式返回图片可选 'jpg','jpeg','png','webp'生效时path参数无效
:return: 图片完整路径或字节文本
@ -475,7 +474,7 @@ class ChromiumElement(DrissionElement):
left_top=left_top, right_bottom=right_bottom)
def input(self, vals, clear=True):
"""输入文本或组合键也可用于输入文件路径到input元素文件间用\n间隔)
"""输入文本或组合键也可用于输入文件路径到input元素路径间用\n间隔)
:param vals: 文本值或按键组合
:param clear: 输入前是否清空文本框
:return: None
@ -509,7 +508,7 @@ class ChromiumElement(DrissionElement):
def clear(self, by_js=False):
"""清空元素文本
:param by_js: 是否用js方式清空
:param by_js: 是否用js方式清空为False则用全选+del模拟输入删除
:return: None
"""
if by_js:
@ -541,7 +540,7 @@ class ChromiumElement(DrissionElement):
self.drag_to((offset_x, offset_y), speed)
def drag_to(self, ele_or_loc, speed=40):
"""拖拽当前元素,目标为另一个元素或坐标元组
"""拖拽当前元素,目标为另一个元素或坐标元组(x, y)
:param ele_or_loc: 另一个元素或坐标元组坐标为元素中点的坐标
:param speed: 拖动的速度传入0即瞬间到达
:return: None
@ -575,7 +574,7 @@ class ChromiumElement(DrissionElement):
actions.release()
def _get_obj_id(self, node_id=None, backend_id=None):
"""根据传入node id获取js中的object id
"""根据传入node id或backend id获取js中的object id
:param node_id: cdp中的node id
:param backend_id: backend id
:return: js中的object id
@ -586,7 +585,7 @@ class ChromiumElement(DrissionElement):
return self.page.run_cdp('DOM.resolveNode', backendNodeId=backend_id)['object']['objectId']
def _get_node_id(self, obj_id=None, backend_id=None):
"""根据传入object id获取cdp中的node id
"""根据传入object id或backend id获取cdp中的node id
:param obj_id: js中的object id
:param backend_id: backend id
:return: cdp中的node id
@ -604,7 +603,7 @@ class ChromiumElement(DrissionElement):
return self.page.run_cdp('DOM.describeNode', nodeId=node_id)['node']['backendNodeId']
def _get_ele_path(self, mode):
"""返获取css路径或xpath路径"""
"""返获取绝对的css路径或xpath路径"""
if mode == 'xpath':
txt1 = 'var tag = el.nodeName.toLowerCase();'
txt3 = ''' && sib.nodeName.toLowerCase()==tag'''
@ -644,7 +643,7 @@ class ChromiumElement(DrissionElement):
return f':root{t}' if mode == 'css' else t
def _set_file_input(self, files):
"""上传控件写入路径
"""上传控件写入路径
:param files: 文件路径列表或字符串字符串时多个文件用回车分隔
:return: None
"""
@ -1997,7 +1996,7 @@ class ChromiumWaiter(object):
self._driver = page_or_ele
def ele_delete(self, loc_or_ele, timeout=None):
"""
"""等待元素从DOM中删除
:param loc_or_ele: 要等待的元素可以是已有元素定位符
:param timeout: 超时时间默认读取页面超时时间
:return: 是否等待成功
@ -2005,7 +2004,7 @@ class ChromiumWaiter(object):
return ChromiumElementWaiter(self._driver, loc_or_ele, timeout).delete()
def ele_display(self, loc_or_ele, timeout=None):
"""
"""等待元素变成显示状态
:param loc_or_ele: 要等待的元素可以是已有元素定位符
:param timeout: 超时时间默认读取页面超时时间
:return: 是否等待成功
@ -2013,7 +2012,7 @@ class ChromiumWaiter(object):
return ChromiumElementWaiter(self._driver, loc_or_ele, timeout).display()
def ele_hidden(self, loc_or_ele, timeout=None):
"""
"""等待元素变成隐藏状态
:param loc_or_ele: 要等待的元素可以是已有元素定位符
:param timeout: 超时时间默认读取页面超时时间
:return: 是否等待成功

View File

@ -10,7 +10,7 @@ from .base import DrissionElement, BaseElement
from .chromium_base import ChromiumBase
from .chromium_frame import ChromiumFrame
from .chromium_page import ChromiumPage
from .common.constants import NoneElement
from .commons.constants import NoneElement
from .session_element import SessionElement
from .web_page import WebPage

View File

@ -11,11 +11,11 @@ from warnings import warn
from requests import Session
from .chromium_base import ChromiumBase, Timeout, ChromiumBaseSetter
from .chromium_base import ChromiumBase, Timeout, ChromiumBaseSetter, ChromiumBaseWaiter
from .chromium_driver import ChromiumDriver
from .chromium_tab import ChromiumTab
from .common.browser import connect_browser
from .common.web import set_session_cookies
from .commons.browser import connect_browser
from .commons.web import set_session_cookies
from .configs.chromium_options import ChromiumOptions
from .errors import CallMethodError
from .session_page import DownloadSetter
@ -106,7 +106,7 @@ class ChromiumPage(ChromiumBase):
self._tab_obj.Page.javascriptDialogClosed = self._on_alert_close
self._main_tab = self.tab_id
try:
self.download_set.by_DownloadKit()
self.download_set.by_browser()
except RuntimeError:
pass
@ -178,6 +178,13 @@ class ChromiumPage(ChromiumBase):
self._rect = ChromiumTabRect(self)
return self._rect
@property
def wait(self):
"""返回用于等待的对象"""
if self._wait is None:
self._wait = ChromiumPageWaiter(self)
return self._wait
def get_tab(self, tab_id=None):
"""获取一个标签页对象
:param tab_id: 要获取的标签页id为None时获取当前tab
@ -253,13 +260,6 @@ class ChromiumPage(ChromiumBase):
if read_doc and self.ready_state == 'complete':
self._get_document()
def wait_download_begin(self, timeout=None):
"""等待浏览器下载开始
:param timeout: 等待超时时间为None则使用页面对象timeout属性
:return: 是否等到下载开始
"""
return self.download_set.wait_download_begin(timeout)
def close_tabs(self, tab_ids=None, others=False):
"""关闭传入的标签页,默认关闭当前页。可传入多个
:param tab_ids: 要关闭的标签页id可传入id组成的列表或元组为None时关闭当前页
@ -372,6 +372,23 @@ class ChromiumPage(ChromiumBase):
warn("set_window()方法即将弃用请用set.window.xxxx()方法代替。", DeprecationWarning)
return WindowSetter(self)
def wait_download_begin(self, timeout=None):
"""等待浏览器下载开始
:param timeout: 等待超时时间为None则使用页面对象timeout属性
:return: 是否等到下载开始
"""
warn("wait_download_begin()方法即将弃用请用wait.download_begin()方法代替。", DeprecationWarning)
return self.download_set.wait_download_begin(timeout)
class ChromiumPageWaiter(ChromiumBaseWaiter):
def download_begin(self, timeout=None):
"""等待浏览器下载开始
:param timeout: 等待超时时间为None则使用页面对象timeout属性
:return: 是否等到下载开始
"""
return self._driver.download_set.wait_download_begin(timeout)
class ChromiumTabRect(object):
def __init__(self, page):
@ -526,7 +543,7 @@ class ChromiumDownloadSetter(DownloadSetter):
def _cookies_to_session(self):
"""把driver对象的cookies复制到session对象"""
ua = self._page.driver.Runtime.evaluate(expression='navigator.userAgent;')['result']['value']
ua = self._page.run_cdp('Runtime.evaluate', expression='navigator.userAgent;')['result']['value']
self.session.headers.update({"User-Agent": ua})
set_session_cookies(self.session, self._page.get_cookies(as_dict=True))
@ -576,6 +593,9 @@ class WindowSetter(object):
"""用于设置窗口大小的类"""
def __init__(self, page):
"""
:param page: 页面对象
"""
self._page = page
self._window_id = self._get_info()['windowId']

View File

@ -11,7 +11,7 @@ from typing import Union, Tuple, List
from DownloadKit import DownloadKit
from requests import Session
from .chromium_base import ChromiumBase, ChromiumBaseSetter
from .chromium_base import ChromiumBase, ChromiumBaseSetter, ChromiumBaseWaiter
from .chromium_driver import ChromiumDriver
from .chromium_tab import ChromiumTab
from .configs.chromium_options import ChromiumOptions
@ -55,6 +55,9 @@ class ChromiumPage(ChromiumBase):
@property
def rect(self) -> ChromiumTabRect: ...
@property
def wait(self) -> ChromiumPageWaiter: ...
@property
def main_tab(self) -> str: ...
@ -88,8 +91,6 @@ class ChromiumPage(ChromiumBase):
def _to_tab(self, tab_id: str = None, activate: bool = True, read_doc: bool = True) -> None: ...
def wait_download_begin(self, timeout: Union[int, float] = None) -> bool: ...
def close_tabs(self, tab_ids: Union[str, List[str], Tuple[str]] = None, others: bool = False) -> None: ...
def close_other_tabs(self, tab_ids: Union[str, List[str], Tuple[str]] = None) -> None: ...
@ -107,6 +108,12 @@ class ChromiumPage(ChromiumBase):
def _on_alert_open(self, **kwargs): ...
class ChromiumPageWaiter(ChromiumBaseWaiter):
_driver: ChromiumPage = ...
def download_begin(self, timeout: Union[int, float] = None) -> bool: ...
class ChromiumTabRect(object):
def __init__(self, page: ChromiumPage):
self._page: ChromiumPage = ...

View File

@ -6,7 +6,7 @@
from pathlib import Path
from tempfile import gettempdir, TemporaryDirectory
from DrissionPage.common.tools import port_is_using, clean_folder
from DrissionPage.commons.tools import port_is_using, clean_folder
from .options_manage import OptionsManager

View File

@ -8,7 +8,7 @@ from pathlib import Path
from requests import Session
from requests.structures import CaseInsensitiveDict
from DrissionPage.common.web import cookies_to_tuple, set_session_cookies
from DrissionPage.commons.web import cookies_to_tuple, set_session_cookies
from .options_manage import OptionsManager

View File

@ -8,8 +8,8 @@ from pathlib import Path
from re import search
from typing import Union
from .common.constants import Settings
from .common.tools import unzip
from .commons.constants import Settings
from .commons.tools import unzip
from .configs.chromium_options import ChromiumOptions
from .configs.options_manage import OptionsManager
from .session_page import SessionPage

View File

@ -7,8 +7,8 @@ from abc import abstractmethod
from re import sub
from urllib.parse import quote
from DrissionPage.common.web import format_html
from DrissionPage.common.locator import get_loc
from DrissionPage.commons.web import format_html
from DrissionPage.commons.locator import get_loc
class BaseParser(object):

View File

@ -14,9 +14,9 @@ from selenium.webdriver.chrome.options import Options
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
from tldextract import extract
from DrissionPage.common.tools import get_pid_from_port
from DrissionPage.common.browser import connect_browser
from DrissionPage.common.web import cookies_to_tuple
from DrissionPage.commons.tools import get_pid_from_port
from DrissionPage.commons.browser import connect_browser
from DrissionPage.commons.web import cookies_to_tuple
from DrissionPage.configs.session_options import SessionOptions, session_options_to_dict
from DrissionPage.configs.driver_options import DriverOptions

View File

@ -15,9 +15,9 @@ from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
from .base import DrissionElement, BaseElement
from DrissionPage.common.locator import str_to_loc, get_loc
from DrissionPage.common.tools import get_usable_path
from DrissionPage.common.web import format_html, get_ele_txt
from DrissionPage.commons.locator import str_to_loc, get_loc
from DrissionPage.commons.tools import get_usable_path
from DrissionPage.commons.web import format_html, get_ele_txt
from .session_element import make_session_ele

View File

@ -13,7 +13,7 @@ from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.wait import WebDriverWait
from .base import BasePage
from DrissionPage.common.tools import get_usable_path
from DrissionPage.commons.tools import get_usable_path
from .driver_element import DriverElement, make_driver_ele, Scroll, ElementWaiter
from .session_element import make_session_ele

View File

@ -10,8 +10,8 @@ from lxml.etree import tostring
from lxml.html import HtmlElement, fromstring
from .base import DrissionElement, BasePage, BaseElement
from DrissionPage.common.locator import get_loc
from DrissionPage.common.web import get_ele_txt, make_absolute_link
from DrissionPage.commons.locator import get_loc
from DrissionPage.commons.web import get_ele_txt, make_absolute_link
class SessionElement(DrissionElement):

View File

@ -15,7 +15,7 @@ from tldextract import extract
from .base import BasePage
from DrissionPage.configs.session_options import SessionOptions
from DrissionPage.common.web import cookie_to_dict, set_session_cookies
from DrissionPage.commons.web import cookie_to_dict, set_session_cookies
from .session_element import SessionElement, make_session_ele

View File

@ -9,7 +9,7 @@ from typing import Union
from selenium.webdriver.remote.webelement import WebElement
from .base import BaseElement
from DrissionPage.common.locator import get_loc
from DrissionPage.commons.locator import get_loc
from .driver_element import make_driver_ele
from .session_element import make_session_ele, SessionElement

View File

@ -10,9 +10,9 @@ from lxml.etree import tostring
from lxml.html import HtmlElement, fromstring
from .base import DrissionElement, BasePage, BaseElement
from .common.constants import NoneElement
from .common.locator import get_loc
from .common.web import get_ele_txt, make_absolute_link
from .commons.constants import NoneElement
from .commons.locator import get_loc
from .commons.web import get_ele_txt, make_absolute_link
class SessionElement(DrissionElement):

View File

@ -11,7 +11,7 @@ from .base import DrissionElement, BaseElement
from .chromium_base import ChromiumBase
from .chromium_element import ChromiumElement
from .chromium_frame import ChromiumFrame
from .common.constants import NoneElement
from .commons.constants import NoneElement
from .driver_element import DriverElement
from .driver_page import DriverPage
from .session_page import SessionPage

View File

@ -14,7 +14,7 @@ from requests.structures import CaseInsensitiveDict
from tldextract import extract
from .base import BasePage
from .common.web import cookie_to_dict, set_session_cookies
from .commons.web import cookie_to_dict, set_session_cookies
from .configs.session_options import SessionOptions
from .session_element import SessionElement, make_session_ele

View File

@ -13,7 +13,7 @@ from requests.auth import HTTPBasicAuth
from requests.cookies import RequestsCookieJar
from requests.structures import CaseInsensitiveDict
from .common.constants import NoneElement
from .commons.constants import NoneElement
from .base import BasePage
from .chromium_page import ChromiumPage
from .configs.session_options import SessionOptions

View File

@ -6,10 +6,10 @@ with open("README.md", "r", encoding='utf-8') as fh:
setup(
name="DrissionPage",
version="3.2.0",
version="3.2.1",
author="g1879",
author_email="g1879@qq.com",
description="A module that integrates selenium and requests session, encapsulates common page operations.",
description="Python based web automation tool. It can control the browser and send and receive data packets.",
long_description=long_description,
long_description_content_type="text/markdown",
license="BSD",
@ -36,7 +36,7 @@ setup(
python_requires='>=3.6',
entry_points={
'console_scripts': [
'dp = DrissionPage.common.cli:main',
'dp = DrissionPage.commons.cli:main',
],
},
)