diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py
index 88f02a5..5bb649c 100644
--- a/DrissionPage/chromium_base.py
+++ b/DrissionPage/chromium_base.py
@@ -25,13 +25,14 @@ class ChromiumBase(BasePage):
:param tab_id: 要控制的标签页id,不指定默认为激活的
:param timeout: 超时时间
"""
- super().__init__(timeout)
self._is_loading = None
self._root_id = None
self._debug = False
self._debug_recorder = None
self.timeouts = Timeout(self)
self._connect_browser(address, tab_id)
+ timeout = timeout if timeout is not None else self.timeouts.implicit
+ super().__init__(timeout)
def _connect_browser(self, addr_driver_opts=None, tab_id=None):
"""连接浏览器,在第一次时运行 \n
@@ -280,7 +281,7 @@ class ChromiumBase(BasePage):
:return: None
"""
if implicit is not None:
- self.timeout = implicit
+ self.timeouts.implicit = implicit
if page_load is not None:
self.timeouts.page_load = page_load
@@ -661,14 +662,11 @@ class Timeout(object):
"""用于保存d模式timeout信息的类"""
def __init__(self, page):
- self.page = page
+ self._page = page
+ self.implicit = 10
self.page_load = 30
self.script = 30
- @property
- def implicit(self):
- return self.page.timeout
-
class PageLoadStrategy(object):
"""用于设置页面加载策略的类"""
diff --git a/DrissionPage/chromium_base.pyi b/DrissionPage/chromium_base.pyi
index ec2caa7..16512d9 100644
--- a/DrissionPage/chromium_base.pyi
+++ b/DrissionPage/chromium_base.pyi
@@ -193,13 +193,11 @@ class ChromiumBase(BasePage):
class Timeout(object):
def __init__(self, page: ChromiumBase):
- self.page: ChromiumBase = ...
+ self._page: ChromiumBase = ...
+ self.implicit: float = ...
self.page_load: float = ...
self.script: float = ...
- @property
- def implicit(self) -> float: ...
-
class PageLoadStrategy(object):
def __init__(self, page: ChromiumBase):
diff --git a/DrissionPage/chromium_page.py b/DrissionPage/chromium_page.py
index bd22cfd..052989d 100644
--- a/DrissionPage/chromium_page.py
+++ b/DrissionPage/chromium_page.py
@@ -88,9 +88,10 @@ class ChromiumPage(ChromiumBase):
self._tab_obj.Page.javascriptDialogClosed = self._on_alert_close
def _set_options(self):
+ """从配置中读取设置"""
self.set_timeouts(page_load=self.options.timeouts['pageLoad'] / 1000,
script=self.options.timeouts['script'] / 1000,
- implicit=self.options.timeouts['implicit'] / 1000 if self.timeout is None else self.timeout)
+ implicit=self.options.timeouts['implicit'] / 1000)
self._page_load_strategy = self.options.page_load_strategy
@property
diff --git a/DrissionPage/config.py b/DrissionPage/config.py
index 2dd9128..c09af09 100644
--- a/DrissionPage/config.py
+++ b/DrissionPage/config.py
@@ -42,7 +42,6 @@ class OptionsManager(object):
"""返回paths设置"""
if self._paths is None:
self._paths = self.get_option('paths')
-
return self._paths
@property
@@ -50,7 +49,6 @@ class OptionsManager(object):
"""返回chrome设置"""
if self._chrome_options is None:
self._chrome_options = self.get_option('chrome_options')
-
return self._chrome_options
@property
@@ -58,7 +56,6 @@ class OptionsManager(object):
"""返回session设置"""
if self._session_options is None:
self._session_options = self.get_option('session_options')
-
return self._session_options
def get_value(self, section, item):
@@ -151,6 +148,7 @@ class SessionOptions(object):
self._stream = None
self._trust_env = None
self._max_redirects = None
+ self.timeout = 10
if read_file:
self.ini_path = ini_path or str(Path(__file__).parent / 'configs.ini')
@@ -193,6 +191,8 @@ class SessionOptions(object):
if options_dict.get('max_redirects', None) is not None:
self._max_redirects = options_dict['max_redirects']
+ self.timeout = options_dict.get('timeout', 10)
+
@property
def headers(self):
"""返回headers设置信息"""
diff --git a/DrissionPage/config.pyi b/DrissionPage/config.pyi
index 871da6b..ffe58c9 100644
--- a/DrissionPage/config.pyi
+++ b/DrissionPage/config.pyi
@@ -58,6 +58,7 @@ class SessionOptions(object):
self._stream: bool = ...
self._trust_env: bool = ...
self._max_redirects: int = ...
+ self.timeout: float = ...
@property
def headers(self) -> dict: ...
diff --git a/DrissionPage/configs.ini b/DrissionPage/configs.ini
index 763cf8b..3ea4625 100644
--- a/DrissionPage/configs.ini
+++ b/DrissionPage/configs.ini
@@ -18,4 +18,4 @@ headers = {
"Connection": "keep-alive",
"Accept-Charset": "GB2312,utf-8;q=0.7,*;q=0.7"
}
-
+timeout = 10
\ No newline at end of file
diff --git a/DrissionPage/drission.py b/DrissionPage/drission.py
index b2cbccb..a306171 100644
--- a/DrissionPage/drission.py
+++ b/DrissionPage/drission.py
@@ -113,12 +113,6 @@ class Drission(object):
if active_tab != self._driver.current_window_handle:
self._driver.switch_to.window(active_tab)
- # 反反爬设置
- try:
- self._driver.execute_script('Object.defineProperty(navigator,"webdriver",{get:() => undefined,});')
- except Exception:
- pass
-
return self._driver
@property
diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py
index 57a8fdb..0c5c8ec 100644
--- a/DrissionPage/driver_element.py
+++ b/DrissionPage/driver_element.py
@@ -329,7 +329,6 @@ class DriverElement(DrissionElement):
:param filter_loc: 筛选条件,可用selenium的(By, str),也可用本库定位语法
:return: DriverElement对象
"""
- index, filter_loc = _exchange_arguments(index, filter_loc)
eles = self._get_relative_eles('left', filter_loc)
return eles[index - 1] if index <= len(eles) else None
@@ -339,7 +338,6 @@ class DriverElement(DrissionElement):
:param filter_loc: 筛选条件,可用selenium的(By, str),也可用本库定位语法
:return: DriverElement对象
"""
- index, filter_loc = _exchange_arguments(index, filter_loc)
eles = self._get_relative_eles('right', filter_loc)
return eles[index - 1] if index <= len(eles) else None
@@ -349,7 +347,6 @@ class DriverElement(DrissionElement):
:param filter_loc: 筛选条件,可用selenium的(By, str),也可用本库定位语法
:return: DriverElement对象
"""
- index, filter_loc = _exchange_arguments(index, filter_loc)
eles = self._get_relative_eles('left', filter_loc)
return eles[index - 1] if index <= len(eles) else None
@@ -359,7 +356,6 @@ class DriverElement(DrissionElement):
:param filter_loc: 筛选条件,可用selenium的(By, str),也可用本库定位语法
:return: DriverElement对象
"""
- index, filter_loc = _exchange_arguments(index, filter_loc)
eles = self._get_relative_eles('left', filter_loc)
return eles[index - 1] if index <= len(eles) else None
@@ -369,7 +365,6 @@ class DriverElement(DrissionElement):
:param filter_loc: 筛选条件,可用selenium的(By, str),也可用本库定位语法
:return: DriverElement对象
"""
- index, filter_loc = _exchange_arguments(index, filter_loc)
eles = self._get_relative_eles('near', filter_loc)
return eles[index - 1] if index <= len(eles) else None
diff --git a/DrissionPage/driver_page.py b/DrissionPage/driver_page.py
index 3610993..68d6b26 100644
--- a/DrissionPage/driver_page.py
+++ b/DrissionPage/driver_page.py
@@ -67,12 +67,6 @@ class DriverPage(BasePage):
"""
retry, interval = self._before_connect(url, retry, interval)
self._url_available = self._d_connect(self._url, times=retry, interval=interval, show_errmsg=show_errmsg)
-
- try:
- self._driver.execute_script('Object.defineProperty(navigator,"webdriver",{get:() => undefined,});')
- except Exception:
- pass
-
return self._url_available
def ele(self, loc_or_ele, timeout=None):
diff --git a/DrissionPage/session_page.py b/DrissionPage/session_page.py
index 87a516a..f3a6a9b 100644
--- a/DrissionPage/session_page.py
+++ b/DrissionPage/session_page.py
@@ -20,14 +20,16 @@ from .session_element import SessionElement, make_session_ele
class SessionPage(BasePage):
"""SessionPage封装了页面操作的常用功能,使用requests来获取、解析网页"""
- def __init__(self, session_or_options=None, timeout=10):
+ def __init__(self, session_or_options=None, timeout=None):
"""初始化 \n
:param session_or_options: Session对象或SessionOptions对象
- :param timeout: 连接超时时间
+ :param timeout: 连接超时时间,为None时从ini文件读取
"""
- super().__init__(timeout)
self._response = None
+ self.timeout = 10
self._create_session(session_or_options)
+ timeout = timeout if timeout is not None else self.timeout
+ super().__init__(timeout)
def _create_session(self, Session_or_Options):
"""创建内建Session对象
@@ -37,6 +39,7 @@ class SessionPage(BasePage):
if Session_or_Options is None or isinstance(Session_or_Options, SessionOptions):
options = Session_or_Options or SessionOptions()
self._set_session(options.as_dict())
+ self.timeout = options.timeout
elif isinstance(Session_or_Options, Session):
self._session = Session_or_Options
diff --git a/DrissionPage/session_page.pyi b/DrissionPage/session_page.pyi
index fcb3382..2c8a31c 100644
--- a/DrissionPage/session_page.pyi
+++ b/DrissionPage/session_page.pyi
@@ -18,7 +18,7 @@ from .config import SessionOptions
class SessionPage(BasePage):
def __init__(self,
session_or_options: Union[Session, SessionOptions] = None,
- timeout: float = 10):
+ timeout: float = None):
self._session: Session = ...
self._url: str = ...
self._response: Response = ...
diff --git a/DrissionPage/web_page.py b/DrissionPage/web_page.py
index 600dfb9..c95fdfc 100644
--- a/DrissionPage/web_page.py
+++ b/DrissionPage/web_page.py
@@ -19,9 +19,10 @@ from .chromium_driver import ChromiumDriver
class WebPage(SessionPage, ChromiumPage, BasePage):
"""整合浏览器和request的页面类"""
- def __init__(self, mode='d', timeout=10, tab_id=None, driver_or_options=None, session_or_options=None):
+ def __init__(self, mode='d', timeout=None, tab_id=None, driver_or_options=None, session_or_options=None):
"""初始化函数 \n
:param mode: 'd' 或 's',即driver模式和session模式
+ :param tab_id: 要控制的标签页id,不指定默认为激活的
:param timeout: 超时时间,d模式时为寻找元素时间,s模式时为连接时间,默认10秒
:param driver_or_options: ChromiumDriver对象或DriverOptions对象,只使用s模式时应传入False
:param session_or_options: Session对象或SessionOptions对象,只使用d模式时应传入False
@@ -32,7 +33,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
self._debug = False
self._debug_recorder = None
- super(ChromiumBase, self).__init__(timeout) # 调用Base的__init__()
self._session = None
self._tab_obj = None
self._is_loading = False
@@ -46,6 +46,9 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
if self._mode == 'd':
self._to_d_mode()
+ t = timeout if timeout is not None else self.timeouts.implicit
+ super(ChromiumBase, self).__init__(t) # 调用Base的__init__()
+
def __call__(self, loc_or_str, timeout=None):
"""在内部查找元素 \n
例:ele = page('@id=ele_id') \n
@@ -138,6 +141,19 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
"""返回 session 保存的url"""
return self._response.url if self._response else None
+ @property
+ def timeout(self):
+ """返回通用timeout设置"""
+ return self.timeouts.implicit
+
+ @timeout.setter
+ def timeout(self, second):
+ """设置通用超时时间 \n
+ :param second: 秒数
+ :return: None
+ """
+ self.set_timeouts(implicit=second)
+
def get(self, url, show_errmsg=False, retry=None, interval=None, timeout=None, **kwargs):
"""跳转到一个url \n
:param url: 目标url
@@ -368,44 +384,58 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
return super(SessionPage, self)._ele(loc_or_ele, timeout=timeout, single=single, relative=relative)
def _set_driver_options(self, driver_or_Options):
- """处理driver设置"""
+ """处理driver设置
+ :param driver_or_Options: ChromiumDriver对象或DriverOptions对象
+ :return: None
+ """
+ if isinstance(driver_or_Options, ChromiumDriver):
+ self._connect_browser(driver_or_Options)
+ self._has_driver = True
+ return
+
if driver_or_Options is None:
self._driver_options = DriverOptions()
elif driver_or_Options is False:
self._driver_options = DriverOptions(read_file=False)
- elif isinstance(driver_or_Options, ChromiumDriver):
- self._connect_browser(driver_or_Options)
- self._has_driver = True
-
elif isinstance(driver_or_Options, DriverOptions):
self._driver_options = driver_or_Options
else:
raise TypeError('driver_or_options参数只能接收WebDriver, Options, DriverOptions或False。')
+ timeouts = self._driver_options.timeouts
+ self.set_timeouts(timeouts['implicit'], timeouts['pageLoad'], timeouts['script'])
+
def _set_session_options(self, Session_or_Options):
- """处理session设置"""
- if Session_or_Options is None:
- self._session_options = SessionOptions().as_dict()
-
- elif Session_or_Options is False:
- self._session_options = SessionOptions(read_file=False).as_dict()
-
- elif isinstance(Session_or_Options, Session):
+ """处理session设置
+ :param Session_or_Options: Session对象或SessionOptions对象
+ :return: None
+ """
+ if isinstance(Session_or_Options, Session):
self._session = Session_or_Options
self._has_session = True
+ return
+
+ if Session_or_Options is None:
+ so = SessionOptions()
+
+ elif Session_or_Options is False:
+ so = SessionOptions(read_file=False)
elif isinstance(Session_or_Options, SessionOptions):
- self._session_options = Session_or_Options.as_dict()
+ so = Session_or_Options
elif isinstance(Session_or_Options, dict):
- self._session_options = Session_or_Options
+ so = Session_or_Options
else:
raise TypeError('session_or_options参数只能接收Session, dict, SessionOptions或False。')
+ self._session_options = so.as_dict()
+ self.set_timeouts(implicit=so.timeout)
+
def quit(self):
"""关闭浏览器,关闭session"""
if self._has_session:
diff --git a/DrissionPage/web_page.pyi b/DrissionPage/web_page.pyi
index c7a7edd..b068044 100644
--- a/DrissionPage/web_page.pyi
+++ b/DrissionPage/web_page.pyi
@@ -54,7 +54,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def mode(self) -> str: ...
@property
- def cookies(self)->Union[dict, list]: ...
+ def cookies(self) -> Union[dict, list]: ...
@property
def session(self) -> Session: ...
@@ -74,6 +74,12 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
@property
def _session_url(self) -> str: ...
+ @property
+ def timeout(self) -> float: ...
+
+ @timeout.setter
+ def timeout(self, second: float) -> None: ...
+
def get(self,
url: str,
show_errmsg: bool = False,
@@ -155,6 +161,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
def _set_driver_options(self, driver_or_Options: Union[ChromiumDriver, DriverOptions]) -> None: ...
- def _set_session_options(self, Session_or_Options:Union[Session, SessionOptions]) -> None: ...
+ def _set_session_options(self, Session_or_Options: Union[Session, SessionOptions]) -> None: ...
def quit(self) -> None: ...
diff --git a/docs/WebPage使用方法/3.10动作链.md b/docs/WebPage使用方法/3.10动作链.md
index f76e3ca..ee8bd3a 100644
--- a/docs/WebPage使用方法/3.10动作链.md
+++ b/docs/WebPage使用方法/3.10动作链.md
@@ -32,13 +32,13 @@ from DrissionPage import ActionChains
创建动作链对象非常简单,只要把`WebPage`对象或`ChromiumPage`对象传入即可。动作链只在这个页面上生效。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------ | ---------------------------- | --- | ------------ |
| `page` | `WebPage`对象或`ChromiumPage`对象 | 无 | 动作链要操作的浏览器页面 |
-**示例:**
+**◽ 示例:**
```python
from DrissionPage import WebPage, ActionChains
@@ -53,21 +53,21 @@ ac = ActionChains(page)
此方法用于移动鼠标到元素中点,或页面上的某个绝对坐标。可设置偏移量,当带偏移量时,偏移量相对于元素左上角坐标。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------------ | ----------------------------------------- | --- | --------------------------------------- |
| `ele_or_loc` | `ChrmoiumElement`、`str`、`Tuple[int, int]` | 无 | 元素对象、文本定位符或绝对坐标,坐标为`tuple`(int, int) 形式 |
| `offset_x` | `int` | 0 | x 轴偏移量,向右为正,向左为负 |
| `offset_y` | `int` | 0 | y 轴偏移量,向下为正,向上为负 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**示例:**
+**◽ 示例:**
```python
ele = page('tag:a')
@@ -78,20 +78,20 @@ ac.move_to(ele_or_loc=ele) # 使鼠标移动过到 ele 元素上
此方法用于使鼠标相对当前位置移动若干距离。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ---------- | ----- | --- | ---------------- |
| `offset_x` | `int` | 0 | x 轴偏移量,向右为正,向左为负 |
| `offset_y` | `int` | 0 | y 轴偏移量,向下为正,向上为负 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**示例:**
+**◽ 示例:**
```python
ac.move(300, 0) # 鼠标向右移动 300 像素
@@ -101,19 +101,19 @@ ac.move(300, 0) # 鼠标向右移动 300 像素
此方法用于使鼠标相对当前位置向上移动若干距离。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------- | ----- | --- | -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**示例:**
+**◽ 示例:**
```python
ac.up(50) # 鼠标向上移动 50 像素
@@ -123,15 +123,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于使鼠标相对当前位置向下移动若干距离。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------- | ----- | --- | -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -139,15 +139,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于使鼠标相对当前位置向左移动若干距离。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------- | ----- | --- | -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -155,15 +155,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于使鼠标相对当前位置向右移动若干距离。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------- | ----- | --- | -------- |
| `pixel` | `int` | 无 | 鼠标移动的像素值 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -173,15 +173,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于单击鼠标左键,单击前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要点击的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -189,15 +189,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于单击鼠标右键,单击前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要点击的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -205,15 +205,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于单击鼠标中键,单击前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要点击的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -221,15 +221,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于按住鼠标左键不放,按住前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要按住的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -237,15 +237,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于释放鼠标左键,释放前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要释放的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -253,15 +253,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于按住鼠标右键不放,按住前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要按住的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -269,15 +269,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于释放鼠标右键,释放前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要释放的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -285,15 +285,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于按住鼠标中键不放,按住前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要按住的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -301,15 +301,15 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于释放鼠标中键,释放前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ----------------------- | ------ | -------------- |
| `on_ele` | `ChromiumElement`、`str` | `None` | 要释放的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -319,17 +319,17 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于滚动鼠标滚轮,滚动前可先移动到元素上。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
-| --------- | ----------------------- | ------ | -------------- |
-| `delta_x` | `int` | 0 | 滚轮 x 轴变化值 |
-| `delta_y` | `str` | 0 | 滚轮 y 轴变化值 |
-| `on_ele` | `ChromiumElement`、`str` | `None` | 要滚动的元素对象或文本定位符 |
+| 名称 | 类型 | 默认 | 说明 |
+| --------- | ----------------------- | ------ | ------------------- |
+| `delta_x` | `int` | 0 | 滚轮 x 轴变化值,向右为正,向左为负 |
+| `delta_y` | `str` | 0 | 滚轮 y 轴变化值,向下为正,向上为负 |
+| `on_ele` | `ChromiumElement`、`str` | `None` | 要滚动的元素对象或文本定位符 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -339,19 +339,19 @@ ac.up(50) # 鼠标向上移动 50 像素
此方法用于按下键盘按键,特殊字符见 Keys。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ----- | ----- | --- | ---- |
| `key` | `str` | 无 | 按键键值 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**示例:**
+**◽ 示例:**
```python
from DrissionPage.keys import Keys
@@ -363,15 +363,15 @@ ac.key_down(Keys.CTRL) # 按下 ctrl 键
此方法用于提起键盘按键,特殊字符见 Keys。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ----- | ----- | --- | ---- |
| `key` | `str` | 无 | 按键键值 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -379,15 +379,15 @@ ac.key_down(Keys.CTRL) # 按下 ctrl 键
此方法用于输入一段文本。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| ------ | ----- | --- | ------ |
| `text` | `str` | 无 | 要输入的文本 |
-**返回:**
+**◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
@@ -397,19 +397,19 @@ ac.key_down(Keys.CTRL) # 按下 ctrl 键
此方法用于在动作链中插入停顿。
-**参数:**
+**◽ 参数:**
-| 名称 | 数据类型 | 默认值 | 说明 |
+| 名称 | 类型 | 默认 | 说明 |
| -------- | ------- | --- | ---- |
| `second` | `float` | 无 | 等待秒数 |
-**返回:**
+ **◽ 返回:**
-| 数据类型 | 说明 |
+| 类型 | 说明 |
| -------------- | ------- |
| `ActionChains` | 动作链对象本身 |
-**示例:**
+**◽ 示例:**
```python
ac.wait(3) # 停顿 3 秒
diff --git a/docs/WebPage使用方法/3.1创建页面对象.md b/docs/WebPage使用方法/3.1创建页面对象.md
index 68c2d37..0f17825 100644
--- a/docs/WebPage使用方法/3.1创建页面对象.md
+++ b/docs/WebPage使用方法/3.1创建页面对象.md
@@ -10,40 +10,7 @@
这 3 种页面对象的使用逻辑是一致的,使用时可根据实际须要选择使用。
-# ✔️ 三种页面对象
-
-## 📍 `WebPage`
-
-`WebPage`对象封装了常用的网页操作,并实现在浏览器和 requests 两种模式之间的切换。
-
-**初始化参数:**
-
-- `mode`:初始化时模式,`'d'`或`'s'`,默认为`'d'`
-- `timeout`:超时时间,s 模式时为连接时间,d 模式时为查找元素、处理弹出框、输入文本等超时时间
-- `driver_or_options`:`ChromiumDriver`对象或`DriverOptions`对象,为`None`时使用 ini 文件配置,为`False`时不读取 ini 文件
-- `session_or_options`:`Session`对象或`SessionOptions`对象,为`None`时使用 ini 文件配置,为`False`时不读取 ini 文件
-
-## 📍 `ChromiumPage`
-
-`ChroumiumPage`对象纯粹用于操作浏览器,不能切换模式。一个该对象对应的是浏览器上一个标签页。
-
-**初始化参数:**
-
-- `addr_driver_opts`:浏览器信息,可以是 '地址:端口'字符串、`ChromiumDriver`对象,或`DriverOptions`对象
-
-- `tab_id`:要控制的标签页id,不指定默认为激活的
-
-- `timeout`:总体超时时间
-
-## 📍 `SessionPage`
-
-`SessionPage`对象纯粹用于收发数据包,不能切换模式,产生的元素对象为`SessionElement`。
-
-**初始化参数:**
-
-- `session_or_options`:`Session`对象或`SessionOptions`对象
-
-- `timeout`:连接超时时间
+!>**注意:**
如果有已经打开的同类型浏览器,请先关闭,或者按照下文“多浏览器共存”内容设置。否则会报错。
# ✔️ 直接创建
@@ -54,7 +21,7 @@
```python
# 默认以 d 模式创建页面对象
-page = WebPage('d')
+page = WebPage()
# 指定以 s 模式创建页面对象
page = WebPage('s')
@@ -68,16 +35,18 @@ page = SessionPage()
# ✔️ 通过配置信息创建
-本库有两种管理配置信息的对象,`DriverOptions`和`SessionOptions`,分别对应 d 模式和 s 模式的配置。须要时,可以创建相应的配置对象进行设置。
+本库有两种管理配置信息的对象,`DriverOptions`和`SessionOptions`,分别对应控制浏览器和收发数据包的配置。须要时,可以创建相应的配置对象进行设置。
-## 📍 `DriverOptions`类
+## 📍 `DriverOptions`
`DriverOptions`用于管理创建浏览器时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
-初始化参数:
+**◽ 初始化参数:**
-- read_file:是否从 ini 文件中读取配置信息
-- ini_path:ini 文件路径,为`None`则读取默认 ini 文件
+| 名称 | 类型 | 默认 | 说明 |
+| ----------- | ------ | ------ | ------------------------ |
+| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
+| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
!>**注意:**
浏览器创建后再修改这个配置是没有效果的。
@@ -91,49 +60,44 @@ do = DriverOptions().set_paths(chrome_path=r'D:\chrome.exe', local_port=9333)
page = WebPage(driver_or_options=do)
```
-用 ChroumiumPage 创建页面对象
-
-```python
-page = ChromiumPage(addr_driver_opts=do)
-
-# 也可以直接把要控制的浏览器地址写在参数里
-page = ChromiumPage(addr_driver_opts='127.0.0.1:9333')
-```
-
-## 📍 `SessionOptions`类
+## 📍 `SessionOptions`
`SessionOptions`用于管理创建`Session`对象时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
-初始化参数:
+**◽ 初始化参数:**
-- read_file:是否从 ini 文件中读取配置信息
-- ini_path:ini 文件路径,为`None`则读取默认 ini 文件
+| 名称 | 类型 | 默认 | 说明 |
+| ----------- | ------ | ------ | ------------------------ |
+| `read_file` | `bool` | `True` | 是否从 ini 文件中读取配置信息 |
+| `ini_path` | `str` | `None` | 文件路径,为`None`则读取默认 ini 文件 |
!>**注意:**
`Session`对象创建后再修改这个配置是没有效果的。
```python
# 导入 SessionOptions
-from DrissionPage import WebPage, SessionOptions
+from DrissionPage import SessionPage, SessionOptions
proxies = {'http': 'http://127.0.0.1:1080',
- 'https': 'https://127.0.0.1:1080'}
+ 'https': 'http://127.0.0.1:1080'}
# 创建配置对象,不从 ini 文件读取,并设置代理信息
so = SessionOptions(read_file=False).set_proxies(proxies)
-# 用该配置创建页面对象(s 模式)
-page = WebPage(mode='s', session_or_options=so)
-```
-
-用 SessionPage 创建页面对象
-
-```python
+# 用该配置创建页面对象
page = SessionPage(session_or_options=so)
```
-d 模式的配置和 s 模式的配置是可以同时使用的,不会互相影响。
+`WebPage`创建时浏览器配置和`Session`对象配置是可以同时使用的,不会互相影响。
```python
-page = WebPage(mode='s', session_or_options=so, driver_or_options=do)
+page = WebPage(session_or_options=so, driver_or_options=do)
+```
+
+## 📍 直接指定地址创建
+
+`ChromiumPage`可以直接接收浏览器地址来创建,格式为 'ip:port'。
+
+```python
+page = ChromiumPage(addr_driver_opts='127.0.0.1:9333')
```
## 📍 使用其它 ini 文件创建
@@ -147,20 +111,41 @@ do = DriverOptinos(ini_path=r'./config1.ini')
page = WebPage(driver_or_options=do)
```
-# ✔️ 传递驱动器
+# ✔️ 传递控制权
当须要使用多个页面对象共同操作一个页面时,可在对象间传递驱动器。
```python
from DrissionPage import WebPage
+# 创建第一个页面
page1 = WebPage()
+# 获取页面对象的浏览器控制器
driver = page1.driver
+# 获取页面对象的Session对象
session = page1.session
+# 把两个控制器对象在第二个页面对象初始化时传递进去
page2 = WebPage(driver_or_options=driver, session_or_options=session)
```
-# ✔️ 接管手动打开的浏览器
+# ✔️ 接管已打开的浏览器
+
+页面对象创建时,只要指定的 ip:port 中已有浏览器在运行,就会直接接管。无论浏览器是下面哪种方式启动的。
+
+## 📍 用程序启动的浏览器
+
+默认情况下,创建浏览器页面对象时会自动启动一个浏览器。只要这个浏览器不关闭,下次运行程序时会接管同一个浏览器继续操作(配置的 ip:port 信息不变)。
+
+这种方式极大地方便了程序的调试,使程序不必每次重新开始,可以单独调试某个功能。
+
+```python
+from DrissionPage import ChromiumPage
+
+# 创建对象同时启动浏览器,如果浏览器已经存在,则接管它
+page = ChromiumPage()
+```
+
+## 📍 手动打开的浏览器
如果须要手动打开浏览器再接管,可以这样做:
@@ -170,13 +155,16 @@ page2 = WebPage(driver_or_options=driver, session_or_options=session)
- 点击确定
-- 在程序中的浏览器配置中指定接管该端口浏览器,如下:
+- 在程序中的浏览器配置中指定接管该端口浏览器
+
+文件快捷方式的目标路径设置:
```
-# 文件快捷方式的目标路径设置
D:\chrome.exe --remote-debugging-port=9222
```
+程序代码:
+
```python
from DrissionPage import WebPage, DriverOptions
@@ -184,80 +172,108 @@ do = DriverOptions().set_paths(local_port=9222)
page = WebPage(driver_or_options=do)
```
-?>**Tips:**
接管使用 bat 文件打开的浏览器也是一样做法做法。
接管浏览器时只有`local_port`、`debugger_address`参数是有效的。
+!> **注意:**
接管浏览器时只有`local_port`、`debugger_address`参数是有效的。
-# ✔️ 多 Chrome 浏览器共存
+## 📍 bat 文件启动的浏览器
-如果想要同时操作多个 Chrome 浏览器,或者自己在使用 Chrome 上网,同时控制另外几个跑自动化,就须要给这些被程序控制的浏览器设置单独的端口和用户文件夹,否则会造成冲突。具体用`DriverOptions`对象进行设置,示例如下:
+可以把上一种方式的目标路径设置写进 bat 文件(Windows系统),运行 bat 文件来启动浏览器,再用程序接管。
+
+新建一个文本文件,在里面输入以下内容(路径改为自己电脑的):
+
+```console
+"D:\chrome.exe" --remote-debugging-port=9222
+```
+
+保存后把后缀改成 bat,然后双击运行就能在 9222 端口启动一个浏览器。程序代码则和上一个方法一致。
+
+# ✔️ 多浏览器共存
+
+## 📍 用程序启动的浏览器
+
+如果想要同时操作多个浏览器,或者自己在使用其中一个上网,同时控制另外几个跑自动化,就须要给这些被程序控制的浏览器设置单独的**端口**和**用户文件夹**,否则会造成冲突。具体用`DriverOptions`对象进行设置,示例如下:
```python
-from DrissionPage import DriverOptions
+from DrissionPage import ChromiumPage, DriverOptions
do1 = DriverOptions().set_paths(local_port=9111, user_data_path=r'D:\data1')
do2 = DriverOptions().set_paths(local_port=9222, user_data_path=r'D:\data2')
-page1 = WebPage(driver_or_options=do1)
-page2 = WebPage(driver_or_options=do2)
+page1 = ChromiumPage(driver_or_options=do1)
+page2 = ChromiumPage(driver_or_options=do2)
page1.get('https://www.baidu.com')
page2.get('http://www.163.com')
```
-如果要接管多个手动打开的浏览器,每个浏览器后面的参数都要添加`--remote-debugging-port`和`--user-data-dir`参数。示例如下:
+?>**Tips:**
每个浏览器都要设置独立的端口号和用户文件夹,二者缺一不可。
+
+## 📍 bat 文件启动的浏览器
+
+如果要接管多个 bat 文件打开的浏览器,每个浏览器的参数都要添加`--remote-debugging-port`和`--user-data-dir`参数。浏览器路径则是一样的。示例如下:
+
+bat 文件1
```
-# 浏览器1目标设置
-D:\chrome.exe --remote-debugging-port=9111 --user-data-dir=D:\data1
-
-# 浏览器2目标设置
-D:\chrome.exe --remote-debugging-port=9222 --user-data-dir=D:\data2
+"D:\chrome.exe" --remote-debugging-port=9111 --user-data-dir=D:\data1
```
+bat 文件2
+
+```
+"D:\chrome.exe“ --remote-debugging-port=9222 --user-data-dir=D:\data2
+```
+
+程序代码:
+
```python
-from DrissionPage import DriverOptions
+from DrissionPage import ChromiumPage, DriverOptions
do1 = DriverOptions().set_paths(local_port=9111)
do2 = DriverOptions().set_paths(local_port=9222)
-page1 = WebPage(driver_or_options=do1)
-page2 = WebPage(driver_or_options=do2)
+page1 = ChromiumPage(driver_or_options=do1)
+page2 = ChromiumPage(driver_or_options=do2)
```
-?> **Tips:**
使用 bat 文件打开浏览器再接管操作是一样的。
+# ✔️ 页面对象初始化 API
-# ✔️ 一些技巧
+## 📍 `ChromiumPage`
-事实上,本库默认启动浏览器的方式是先通过程序在 9222(或用户指定的)端口运行一个浏览器进程,然后通过程序接管。这种做法有很多好处:
+`ChroumiumPage`对象纯粹用于操作浏览器,不能切换模式。一个该对象对应的是浏览器上一个标签页。
-## 📍 可重复使用的浏览器对象
+**◽ 初始化参数:**
-当程序运行完毕,浏览器不会主动关闭,下次再运行的时候可以直接在当前状态下继续运行。于是无须每次打开新的浏览器对象,无须从最开始步骤重新运行整个程序,一些前置条件(如登录)也无须每次运行,大大提高开发效率。
+| 名称 | 类型 | 默认 | 说明 |
+| ------------------ | -------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------- |
+| `addr_driver_opts` | `str`、`ChromiumDriver`、`DriverOptions` | `None` | 浏览器启动配置或接管信息;传入' ip:port' 字符串或`ChromiumDriver`时接管浏览器,传入`DriverOptions`时按配置启动浏览器,为`None`时使用配置文件配置启动浏览器 |
+| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
+| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
-## 📍 简便的调试方式
+## 📍 `SessionPage`
-通过重复使用浏览器对象,用户可以把浏览器页面调整到某个状态再用程序接管,对调试某个特定问题效率极高。比如有些通过很多步骤才能到达的页面,如果每次重新运行会花费大量时间,而将页面固定再由程序接管,测试各种细节非常方便快捷。
+`SessionPage`对象纯粹用于收发数据包,不能切换模式,产生的元素对象为`SessionElement`。
-## 📍 一行代码传递登录状态到 requests
+**◽ 初始化参数:**
-本库的一个特点是打通了浏览器和`requests`之间的登录状态,我们可以手动登录浏览器,再用程序接管,然后切换到 s 模式,这时 s 模式的`Session`对象即已活动浏览器的登录信息,无须用`requests`
-处理登录过程,极大地简化了开发复杂程度。示例:
+| 名称 | 类型 | 默认 | 说明 |
+| -------------------- | -------------------------- | ------ | --------------------------------------------------------------- |
+| `session_or_options` | `Session`、`SessionOptions` | `None` | 传入`Session`对象时使用该对象收发数据包;传入`SessionOptions`对象时用该配置创建`Session`对象 |
+| `timeout` | `float` | `None` | 连接超时时间, |
-```python
-# 假设已在 9222 端口打开了一个浏览器,并已登录某网站
-from DrissionPage import WebPage
+## 📍 `WebPage`
-page = WebPage() # 用 d 模式创建页面对象,默认接管 9222 端口
-page.change_mode() # 切换到 s 模式,即使用 requests 进行操作
-page.get('某url...') # 即可已登录状态访问
-```
+`WebPage`对象封装了常用的网页操作,并实现在浏览器和 requests 两种模式之间的切换。
-使用其它端口号:
+**◽ 初始化参数:**
-```python
-from DrissionPage import WebPage, DriverOptions
+| 名称 | 类型 | 默认 | 说明 |
+| -------------------- | --------------------------------------- | ------ | ---------------------------------------------------------------- |
+| `mode` | `str` | `'d'` | 启动时的模式,只能传入`'d'`或`'s'` |
+| `timeout` | `float` | `None` | 整体超时时间,为`None`则从配置文件中读取 |
+| `tab_id` | `str` | `None` | 要控制的标签页id,用于 d 模式,为`None`则控制激活的标签页 |
+| `driver_or_options` | `ChromiumDriver`、`DriverOptions`、`bool` | `None` | 浏览器控制对象或浏览器启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
+| `session_or_options` | `Session`、`SessionOptions`、`bool` | `None` | 收发数据包对象或`Session`启动配置对象;为`None`时使用 ini 文件配置;为`False`时不读取 ini 文件。 |
-do = DriverOptions().set_paths(local_port=9333)
-page = WebPage(driver_or_option=do)
-page.change_mode()
-page.get('某url...')
-```
+**◽ 说明:**
+
+`driver_or_options`和`session_or_options`传入`ChromiumDriver`和`Session`对象时,可在多个页面对象间传递控制权。
diff --git a/docs/版本历史.md b/docs/版本历史.md
index 930a42e..b2239d4 100644
--- a/docs/版本历史.md
+++ b/docs/版本历史.md
@@ -1,12 +1,15 @@
-# v3.0.32
+# v3.0.33
- `WebPage`删除`check_page()`方法
- `DriverOptions`和`easy_set`的`set_paths()`增加`browser_path`参数
- `DriverOptions`增加`browser_path`属性
- `ChromiumFrame`现在支持页面滚动
-- 修改`SessionElement`相对定位参数顺序
- 改进滚动到元素功能
-- 修复一些问题
+- 修改`SessionElement`相对定位参数顺序
+- `SessionPage`也可以从 ini 文件读取 timeout 设置
+- ini 文件中`session_options`增加`timeout`项
+- `SessionOptions`增加`timeout`属性
+- 优化和修复一些问题
# v3.0.31
diff --git a/setup.py b/setup.py
index 8be14a3..45a505c 100644
--- a/setup.py
+++ b/setup.py
@@ -6,7 +6,7 @@ with open("README.md", "r", encoding='utf-8') as fh:
setup(
name="DrissionPage",
- version="3.0.32",
+ version="3.0.33",
author="g1879",
author_email="g1879@qq.com",
description="A module that integrates selenium and requests session, encapsulates common page operations.",