diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py
index 55c85b8..a5682c5 100644
--- a/DrissionPage/chromium_base.py
+++ b/DrissionPage/chromium_base.py
@@ -28,6 +28,7 @@ class ChromiumBase(BasePage):
         self._root_id = None
         self._debug = False
         self._debug_recorder = None
+        self.timeouts = Timeout(self)
         self._connect_browser(address, tab_id)
 
     def _connect_browser(self, addr_tab_opts=None, tab_id=None):
@@ -37,7 +38,6 @@ class ChromiumBase(BasePage):
         :return: None
         """
         self._root_id = None
-        self.timeouts = Timeout(self)
         self._control_session = Session()
         self._control_session.keep_alive = False
         self._first_run = True
@@ -256,14 +256,10 @@ class ChromiumBase(BasePage):
             self._scroll = ChromeScroll(self)
         return self._scroll
 
-    def set_page_load_strategy(self, value):
-        """设置页面加载策略                                    \n
-        :param value: 可选'normal', 'eager', 'none'
-        :return: None
-        """
-        if value not in ('normal', 'eager', 'none'):
-            raise ValueError("只能选择'normal', 'eager', 'none'。")
-        self._page_load_strategy = value
+    @property
+    def set_page_load_strategy(self):
+        """返回用于设置页面加载策略的对象"""
+        return pageLoadStrategy(self)
 
     def set_timeouts(self, implicit=None, page_load=None, script=None):
         """设置超时时间,单位为秒                   \n
@@ -307,7 +303,7 @@ class ChromiumBase(BasePage):
         :param retry: 重试次数
         :param interval: 重试间隔(秒)
         :param timeout: 连接超时时间
-        :return: 目标url是否可用,返回None表示不确定
+        :return: 目标url是否可用
         """
         self._url_available = self._get(url, show_errmsg, retry, interval, timeout)
         return self._url_available
@@ -810,3 +806,34 @@ class Timeout(object):
     @property
     def implicit(self):
         return self.page.timeout
+
+
+class pageLoadStrategy(object):
+    """用于设置页面加载策略的类"""
+
+    def __init__(self, page):
+        """
+        :param page: ChromiumBase对象
+        """
+        self.page = page
+
+    def __call__(self, value):
+        """设置加载策略                                  \n
+        :param value: 可选 'normal', 'eager', 'none'
+        :return: None
+        """
+        if value.lower() not in ('normal', 'eager', 'none'):
+            raise ValueError("只能选择 'normal', 'eager', 'none'。")
+        self.page._page_load_strategy = value
+
+    def set_normal(self):
+        """设置页面加载策略为normal"""
+        self.page._page_load_strategy = 'normal'
+
+    def set_eager(self):
+        """设置页面加载策略为eager"""
+        self.page._page_load_strategy = 'eager'
+
+    def set_none(self):
+        """设置页面加载策略为none"""
+        self.page._page_load_strategy = 'none'
diff --git a/DrissionPage/chromium_base.pyi b/DrissionPage/chromium_base.pyi
index c39576e..c5129b0 100644
--- a/DrissionPage/chromium_base.pyi
+++ b/DrissionPage/chromium_base.pyi
@@ -101,7 +101,8 @@ class ChromiumBase(BasePage):
     @property
     def scroll(self) -> 'ChromeScroll': ...
 
-    def set_page_load_strategy(self, value: str) -> None: ...
+    @property
+    def set_page_load_strategy(self) -> pageLoadStrategy: ...
 
     def set_timeouts(self, implicit: float = ..., page_load: float = ..., script: float = ...) -> None: ...
 
@@ -279,3 +280,16 @@ class Timeout(object):
 
     @property
     def implicit(self) -> float: ...
+
+
+class pageLoadStrategy(object):
+    def __init__(self, page: ChromiumBase):
+        self.page: ChromiumBase = ...
+
+    def __call__(self, value: str) -> None: ...
+
+    def set_normal(self) -> None: ...
+
+    def set_eager(self) -> None: ...
+
+    def set_none(self) -> None: ...
diff --git a/DrissionPage/web_page.py b/DrissionPage/web_page.py
index fbc7076..6aeb95f 100644
--- a/DrissionPage/web_page.py
+++ b/DrissionPage/web_page.py
@@ -5,7 +5,7 @@ from requests import Session
 from tldextract import extract
 
 from .base import BasePage
-from .chromium_base import ChromiumBase
+from .chromium_base import ChromiumBase, Timeout
 from .chromium_page import ChromiumPage
 from .config import DriverOptions, SessionOptions, cookies_to_tuple
 from .session_page import SessionPage
@@ -32,6 +32,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
         self._session = None
         self._tab_obj = None
         self._is_loading = False
+        self.timeouts = Timeout(self)
         self._set_session_options(session_or_options)
         self._set_driver_options(driver_or_options)
         self._setting_tab_id = tab_id
@@ -102,9 +103,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
         if self._session is None:
             self._set_session(self._session_options)
 
-            # if self._proxy:
-            #     self._session.proxies = self._proxy
-
         return self._session
 
     @property
@@ -117,7 +115,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
         """返回用于控制浏览器的Tab对象,会先等待页面加载完毕"""
         while self._is_loading:
             sleep(.1)
-        # self._wait_loading()
         return self._driver
 
     @property
@@ -150,6 +147,8 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
         if self._mode == 'd':
             return super(SessionPage, self).get(url, show_errmsg, retry, interval, timeout)
         elif self._mode == 's':
+            if timeout is None:
+                timeout = self.timeouts.page_load if self._has_driver else self.timeout
             return super().get(url, show_errmsg, retry, interval, timeout, **kwargs)
 
     def ele(self, loc_or_ele, timeout=None):
@@ -291,7 +290,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
                      'name': cookie['name'],
                      'domain': cookie['domain']}
                 result_cookies.append(c)
-            # super(WebPage, self)._wait_driver.Network.setCookies(cookies=result_cookies)
             self._tab_obj.Network.setCookies(cookies=result_cookies)
 
         # 添加cookie到session
diff --git a/docs/使用方法/Drission对象.md b/docs/MixPage使用方法/Drission对象.md
similarity index 100%
rename from docs/使用方法/Drission对象.md
rename to docs/MixPage使用方法/Drission对象.md
diff --git a/docs/使用方法/DriverPage和SessionPage.md b/docs/MixPage使用方法/DriverPage和SessionPage.md
similarity index 100%
rename from docs/使用方法/DriverPage和SessionPage.md
rename to docs/MixPage使用方法/DriverPage和SessionPage.md
diff --git a/docs/使用方法/cookies的使用.md b/docs/MixPage使用方法/cookies的使用.md
similarity index 100%
rename from docs/使用方法/cookies的使用.md
rename to docs/MixPage使用方法/cookies的使用.md
diff --git a/docs/使用方法/下载文件.md b/docs/MixPage使用方法/下载文件.md
similarity index 100%
rename from docs/使用方法/下载文件.md
rename to docs/MixPage使用方法/下载文件.md
diff --git a/docs/使用方法/使用其它系统或浏览器.md b/docs/MixPage使用方法/使用其它系统或浏览器.md
similarity index 100%
rename from docs/使用方法/使用其它系统或浏览器.md
rename to docs/MixPage使用方法/使用其它系统或浏览器.md
diff --git a/docs/使用方法/元素操作.md b/docs/MixPage使用方法/元素操作.md
similarity index 100%
rename from docs/使用方法/元素操作.md
rename to docs/MixPage使用方法/元素操作.md
diff --git a/docs/使用方法/创建页面对象.md b/docs/MixPage使用方法/创建页面对象.md
similarity index 99%
rename from docs/使用方法/创建页面对象.md
rename to docs/MixPage使用方法/创建页面对象.md
index c91de8a..6023035 100644
--- a/docs/使用方法/创建页面对象.md
+++ b/docs/MixPage使用方法/创建页面对象.md
@@ -89,7 +89,8 @@ page = MixPage(mode='s', session_options=so, driver_options=do)
 
 # 传入`Drission`对象创建
 
-在入门指南的基本概念一节里,我们讲过`Drission`对象相当于驱动器的角色。事实上,上述两种方式,`MixPage`都会自动创建一个`Drission`对象用于管理与网站或浏览器的连接,我们当然也可以手动创建并传入`MixPage`。  
+在入门指南的基本概念一节里,我们讲过`Drission`对象相当于驱动器的角色。事实上,上述两种方式,`MixPage`都会自动创建一个`Drission`对象用于管理与网站或浏览器的连接,我们当然也可以手动创建并传入`MixPage`
+。  
 `Drission`一般是不用手动创建的,要手动创建的时候,一般是用于i以下几种情况:
 
 - 指定使用某个配置文件
diff --git a/docs/使用方法/启动配置/Chrome启动配置.md b/docs/MixPage使用方法/启动配置/Chrome启动配置.md
similarity index 100%
rename from docs/使用方法/启动配置/Chrome启动配置.md
rename to docs/MixPage使用方法/启动配置/Chrome启动配置.md
diff --git a/docs/使用方法/启动配置/Session启动配置.md b/docs/MixPage使用方法/启动配置/Session启动配置.md
similarity index 100%
rename from docs/使用方法/启动配置/Session启动配置.md
rename to docs/MixPage使用方法/启动配置/Session启动配置.md
diff --git a/docs/使用方法/启动配置/使用配置文件.md b/docs/MixPage使用方法/启动配置/使用配置文件.md
similarity index 100%
rename from docs/使用方法/启动配置/使用配置文件.md
rename to docs/MixPage使用方法/启动配置/使用配置文件.md
diff --git a/docs/使用方法/启动配置/概述.md b/docs/MixPage使用方法/启动配置/概述.md
similarity index 100%
rename from docs/使用方法/启动配置/概述.md
rename to docs/MixPage使用方法/启动配置/概述.md
diff --git a/docs/使用方法/对接selenium及requests代码.md b/docs/MixPage使用方法/对接selenium及requests代码.md
similarity index 100%
rename from docs/使用方法/对接selenium及requests代码.md
rename to docs/MixPage使用方法/对接selenium及requests代码.md
diff --git a/docs/使用方法/打包程序.md b/docs/MixPage使用方法/打包程序.md
similarity index 100%
rename from docs/使用方法/打包程序.md
rename to docs/MixPage使用方法/打包程序.md
diff --git a/docs/使用方法/查找页面元素.md b/docs/MixPage使用方法/查找页面元素.md
similarity index 100%
rename from docs/使用方法/查找页面元素.md
rename to docs/MixPage使用方法/查找页面元素.md
diff --git a/docs/使用方法/监听浏览器网络数据.md b/docs/MixPage使用方法/监听浏览器网络数据.md
similarity index 99%
rename from docs/使用方法/监听浏览器网络数据.md
rename to docs/MixPage使用方法/监听浏览器网络数据.md
index 4e418e4..5ae4838 100644
--- a/docs/使用方法/监听浏览器网络数据.md
+++ b/docs/MixPage使用方法/监听浏览器网络数据.md
@@ -10,11 +10,9 @@
 
 由于该工具不依赖 DrissionPage,现已独立发布为一个库,但仍然可以在 DrissionPage 中导入。
 
-
-
 !> 为了便于维护,该工具用法请异步 [FlowViewer](https://gitee.com/g1879/FlowViewer) 查看。
 
-# 
+#  
 
 # 简单示例
 
diff --git a/docs/使用方法/获取元素信息.md b/docs/MixPage使用方法/获取元素信息.md
similarity index 99%
rename from docs/使用方法/获取元素信息.md
rename to docs/MixPage使用方法/获取元素信息.md
index fcbaf5b..193a3df 100644
--- a/docs/使用方法/获取元素信息.md
+++ b/docs/MixPage使用方法/获取元素信息.md
@@ -1,6 +1,7 @@
 获取到须要的页面元素后,可以使用元素对象获取元素的信息。
 
-本库有三种元素对象,分别是`DriverElement`、`ShadowRootElement`、`SessionElement`,前两者是 d 模式下通过浏览器页面元素生成,后者由静态文本生成。`DriverElement`和`SessionElement`的基本属性一致。
+本库有三种元素对象,分别是`DriverElement`、`ShadowRootElement`、`SessionElement`,前两者是 d 模式下通过浏览器页面元素生成,后者由静态文本生成。`DriverElement`
+和`SessionElement`的基本属性一致。
 
 `ShadowRootElement`由于是 shadow dom 元素,属性比较其余两种少,下文单独介绍。
 
diff --git a/docs/使用方法/获取网页信息.md b/docs/MixPage使用方法/获取网页信息.md
similarity index 100%
rename from docs/使用方法/获取网页信息.md
rename to docs/MixPage使用方法/获取网页信息.md
diff --git a/docs/使用方法/访问网页.md b/docs/MixPage使用方法/访问网页.md
similarity index 100%
rename from docs/使用方法/访问网页.md
rename to docs/MixPage使用方法/访问网页.md
diff --git a/docs/使用方法/页面操作.md b/docs/MixPage使用方法/页面操作.md
similarity index 100%
rename from docs/使用方法/页面操作.md
rename to docs/MixPage使用方法/页面操作.md
diff --git a/docs/WebPage使用方法/3.1创建页面对象.md b/docs/WebPage使用方法/3.1创建页面对象.md
new file mode 100644
index 0000000..de04108
--- /dev/null
+++ b/docs/WebPage使用方法/3.1创建页面对象.md
@@ -0,0 +1,207 @@
+在入门指南的快速上手一节,我们已经初步了解如何创建页面对象,本节进一步介绍更多功能。
+
+# ✔️ `WebPage`类
+
+`WebPage`对象封装了常用的网页操作,并实现在浏览器和 requests 两种模式之间的切换。
+
+初始化参数:
+
+- mode:初始化时模式,`'d'`或`'s'`,默认为`'d'`
+- timeout:超时时间,s 模式时为连接时间,d 模式时为查找元素、处理弹出框、输入文本等超时时间
+- driver_or_options:`Tab`对象或`DriverOptions`对象,为`None`时使用 ini 文件配置,为`False`时不读取 ini 文件
+- session_or_options:`Session`对象或`SessionOptions`对象,为`None`时使用 ini 文件配置,为`False`时不读取 ini 文件
+
+# ✔️ 直接创建
+
+这种方式代码最简洁,程序会从配置文件中读取配置,自动生成页面对象。可以保持代码简洁。  
+在基本概念一节我们提到过,本库使用配置文件记录常用配置信息,也可以直接把配置写在代码里。  
+?>**Tips:**<br>默认配置文件中,程序使用 9222 端口启动浏览器,浏览器路径为 Chrome。如路径中没找到浏览器执行文件,Windows 系统下程序会在注册表中查找路径,如果还是没找到,则要用下一种方式手动配置路径。
+
+```python
+# 默认以 d 模式创建页面对象
+page = WebPage('d')
+
+# 指定以 s 模式创建页面对象
+page = WebPage('s')
+```
+
+# ✔️ 通过配置信息创建
+
+本库有两种管理配置信息的对象,`DriverOptions`和`SessionOptions`,分别对应 d 模式和 s 模式的配置。须要时,可以创建相应的配置对象进行设置。
+
+## 📍 `DriverOptions`类
+
+`DriverOptions`用于管理创建浏览器时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
+
+初始化参数:
+
+- read_file:是否从 ini 文件中读取配置信息
+- ini_path:ini 文件路径,为`None`则读取默认 ini 文件
+
+!>**注意:**<br>浏览器创建后再修改这个配置是没有效果的。
+
+```python
+# 导入 DriverOptions
+from DrissionPage import WebPage, DriverOptions
+
+# 创建浏览器配置对象,指定浏览器路径和运行端口
+do = DriverOptions().set_paths(chrome_path=r'D:\chrome.exe', local_port=9333)
+# 用该配置创建页面对象
+page = WebPage(driver_or_options=do)
+```
+
+## 📍 `SessionOptions`类
+
+`SessionOptions`用于管理创建`Session`对象时的配置,内置了常用的配置,并能实现链式操作。详细使用方法见“启动配置”一节。
+
+初始化参数:
+
+- read_file:是否从 ini 文件中读取配置信息
+- ini_path:ini 文件路径,为`None`则读取默认 ini 文件
+
+!>**注意:**<br> `Session`对象创建后再修改这个配置是没有效果的。
+
+```python
+# 导入 SessionOptions
+from DrissionPage import WebPage, SessionOptions
+
+proxies = {'http': 'http://127.0.0.1:1080',
+           'https': 'https://127.0.0.1:1080'}
+
+# 创建配置对象,不从 ini 文件读取,并设置代理信息
+so = SessionOptions(read_file=False).set_proxies(proxies)
+# 用该配置创建页面对象(s 模式)
+page = WebPage(mode='s', session_options=so)
+```
+
+d 模式的配置和 s 模式的配置是可以同时使用的,不会互相影响。
+
+```python
+page = WebPage(mode='s', session_options=so, driver_options=do)
+```
+
+## 📍 使用其它 ini 文件创建
+
+以上方法是使用默认 ini 文件中保存的配置信息创建对象,你可以保存一个 ini 文件到别的地方,并在创建对象时指定使用它。
+
+```python
+from DrissionPage import WebPage, DriverOptinos
+
+do = DriverOptinos(ini_path=r'./config1.ini')
+page = WebPage(driver_or_options=do)
+```
+
+# ✔️ 传递驱动器
+
+当须要使用多个页面对象共同操作一个页面时,可在对象间传递驱动器。
+
+```python
+from DrissionPage import WebPage
+
+page1 = WebPage()
+driver = page1.driver
+session = page1.session
+page2 = WebPage(driver_or_options=driver, session_or_options=session)
+```
+
+# ✔️ 接管手动打开的浏览器
+
+如果须要手动打开浏览器再接管,可以这样做:
+
+- 右键点击浏览器图标,选择属性
+
+- 在“目标”路径后面加上` --remote-debugging-port=端口号`(注意最前面有个空格)
+
+- 点击确定
+
+- 在程序中的浏览器配置中指定接管该端口浏览器,如下:
+
+```
+# 文件快捷方式的目标路径设置
+D:\chrome.exe --remote-debugging-port=9222
+```
+
+```python
+from DrissionPage import WebPage, DriverOptions
+
+do = DriverOptions().set_paths(local_port=9222)
+page = WebPage(driver_options=do)
+```
+
+?>**Tips:**<br>接管使用 bat 文件打开的浏览器也是一样做法做法。<br>接管浏览器时只有`local_port`、`debugger_address`参数是有效的。
+
+# ✔️ 多 Chrome 浏览器共存
+
+如果想要同时操作多个 Chrome 浏览器,或者自己在使用 Chrome 上网,同时控制另外几个跑自动化,就须要给这些被程序控制的浏览器设置单独的端口和用户文件夹,否则会造成冲突。具体用`DriverOptions`对象进行设置,示例如下:
+
+```python
+from DrissionPage import 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.get('https://www.baidu.com')
+page2.get('http://www.163.com')
+```
+
+如果要接管多个手动打开的浏览器,每个浏览器后面的参数都要添加`--remote-debugging-port`和`--user-data-dir`参数。示例如下:
+
+```
+# 浏览器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
+```
+
+```python
+from DrissionPage import 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)
+```
+
+?> **Tips:**<br>使用 bat 文件打开浏览器再接管操作是一样的。
+
+# ✔️ 一些技巧
+
+事实上,本库默认启动浏览器的方式是先通过程序在 9222(或用户指定的)端口运行一个浏览器进程,然后通过程序接管。这种做法有很多好处:
+
+## 📍 可重复使用的浏览器对象
+
+当程序运行完毕,浏览器不会主动关闭,下次再运行的时候可以直接在当前状态下继续运行。于是无须每次打开新的浏览器对象,无须从最开始步骤重新运行整个程序,一些前置条件(如登录)也无须每次运行,大大提高开发效率。
+
+## 📍 简便的调试方式
+
+通过重复使用浏览器对象,用户可以把浏览器页面调整到某个状态再用程序接管,对调试某个特定问题效率极高。比如有些通过很多步骤才能到达的页面,如果每次重新运行会花费大量时间,而将页面固定再由程序接管,测试各种细节非常方便快捷。
+
+## 📍 一行代码传递登录状态到 requests
+
+本库的一个特点是打通了浏览器和`requests`之间的登录状态,我们可以手动登录浏览器,再用程序接管,然后切换到 s 模式,这时 s 模式的`Session`对象即已活动浏览器的登录信息,无须用`requests`
+处理登录过程,极大地简化了开发复杂程度。示例:
+
+```python
+# 假设已在 9222 端口打开了一个浏览器,并已登录某网站
+from DrissionPage import WebPage
+
+page = WebPage()  # 用 d 模式创建页面对象,默认接管 9222 端口
+page.change_mode()  # 切换到 s 模式,即使用 requests 进行操作
+page.get('某url...')  # 即可已登录状态访问
+```
+
+使用其它端口号:
+
+```python
+from DrissionPage import WebPage, DriverOptions
+
+do = DriverOptions().set_paths(local_port=9333)
+page = WebPage(driver_option=do)
+page.change_mode()
+page.get('某url...')
+```
diff --git a/docs/WebPage使用方法/3.2访问网页.md b/docs/WebPage使用方法/3.2访问网页.md
new file mode 100644
index 0000000..1ec4bfb
--- /dev/null
+++ b/docs/WebPage使用方法/3.2访问网页.md
@@ -0,0 +1,164 @@
+本节介绍如果访问网页。
+
+# ✔️ d 模式
+
+d 模式下使用`get()`方法访问网页。
+
+## 📍 `get()`方法
+
+该方法用于跳转到一个网址。  
+当连接失败时,程序默认重试 3 次,每次间隔 2 秒,可以通过参数设置重试次数和间隔。   
+d 模式下根据浏览器的状态,还可以通过重写`check_page()`方法实现自定义检查方式。
+
+参数:
+
+- url:目标 url
+- show_errmsg:是否显示和抛出异常。默认不抛出,连接错误会返回`None`
+- retry:重试次数,与页面对象的设置一致,默认 3 次
+- interval:重试间隔(秒),与页面对象的设置一致,默认 2 秒
+- timeout:连接超时时间(秒)
+
+返回:`bool`类型,表示是否连接成功
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage()
+page.get('https://www.baidu.com')
+```
+
+## 📍 设置超时时间和重试参数
+
+网络不稳定的时候访问页面不一定成功,`get()`方法内置了超时和重试功能。通过`retry`、`interval`、`timeout`三个参数进行设置。  
+其中,如不指定`timeout`参数,该参数会使用`WebPage`的`timeouts`属性的`page_load`参数中的值。
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage()
+page.get('https://www.163.com', retry=1, interval=1, timeout=1.5)
+```
+
+## 📍 设置加载策略
+
+通过设置`WebPage`对象的`page_load_strategy`属性,可设置页面停止加载的时机。页面加载时,在到达超时时间,或达到设定的状态,就会停止,可有效节省采集时间。有以下三种模式:
+
+- `'normal'`:常规模式,会等待页面加载完毕。
+
+- `'eager'`:加载完 DOM 即停止加载。
+
+- `'none'`:完成连接即停止加载。
+
+默认设置为`'normal'`。
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage()
+page.set_page_load_strategy.set_eager()
+```
+
+# ✔️ s 模式
+
+s 模式基于 requests,因此可使用 requests 内置的所有请求方式,包括`get()`、`post()`、`head()`、`options()`、`put()`、`patch()`、`delete()`
+。不过本库目前只对`get()`和`post()`做了封装和优化,其余方式可通过调用`WebPage`内置的`Session`对象使用。
+
+## 📍 `get()`方法
+
+`get()`方法使用语法与 requests 的`get()`方法一致,在此基础上增加了重试设置参数。
+
+参数:
+
+- url:目标 url
+- show_errmsg:是否显示和抛出异常,默认不抛出,连接错误会返回 None
+- retry:重试次数,与页面对象的设置一致,默认 3 次
+- interval:重试间隔(秒),与页面对象的设置一致,默认 2 秒
+- timeout:连接超时时间(秒)
+- **kwargs:连接参数,具体见 requests用法
+
+返回:`bool`类型,表示是否连接成功,根据`Response`对象的`status_code`参数决定
+
+s 模式的`**kwargs`参数与 requests 中该参数使用方法一致,但有一个特点,如果该参数中设置了某一项(如`headers`),该项中的每个项会覆盖从配置中读取的同名项,而不会整个覆盖。  
+就是说,如果想继续使用配置中的`headers`信息,而只想修改其中一项,只需要传入该项的值即可。这样可以简化代码逻辑。  
+与 requests 不一样,`get()`方法不返回`Response`对象以获取结果,处理返回结果的方式详见后面章节。
+
+实用功能:
+
+- 程序会根据要访问的网址自动在`headers`中加入`Host`和`Referer`项
+- 程序会自动从返回内容中确定编码,一般情况无须手动设置
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage('s')
+
+url = 'https://www.baidu.com'
+headers = {'referer': 'gitee.com'}
+cookies = {'name': 'value'}
+proxies = {'http': '127.0.0.1:1080', 'https': '127.0.0.1:1080'}
+page.get(url, headers=headers, cookies=cookies, proxies=proxies)
+```
+
+## 📍 `post()`方法
+
+此方法是用 post 方式请求页面。用法与`get()`一致。调用时,`WebPage`对象会自动切换到 s 模式。
+
+参数:
+
+- url:目标 url
+- data:提交的数据,可以是`dict`或`str`类型
+- json:提交的数据,可以是`dict`或`str`类型
+- show_errmsg:是否显示和抛出异常,默认不抛出,连接错误会返回 None
+- retry:重试次数,与页面对象的设置一致,默认 3 次
+- interval:重试间隔(秒),与页面对象的设置一致,默认 2 秒
+- **kwargs:连接参数,s 模式专用
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage('s')
+data = {'username': 'xxxxx', 'pwd': 'xxxxx'}
+
+page.post('http://example.com', data=data)
+# 或
+page.post('http://example.com', json=data)
+```
+
+`data`参数和`json`参数都可接收`str`和`dict`格式数据,即有以下 4 种传递数据的方式:
+
+```python
+# 向 data 参数传入字符串
+page.post(url, data='abc=123')
+
+# 向 data 参数传入字典
+page.post(url, data={'abc': '123'})
+
+# 向 json 参数传入字符串
+page.post(url, json='abc=123')
+
+# 向 json 参数传入字典
+page.post(url, json={'abc': '123'})
+```
+
+具体使用哪种,按服务器要求而定。
+
+## 📍 其它请求方式
+
+本库只针对常用的 get 和 post 方式作了优化,但也可以通过提取页面对象内的`Session`对象以原生 requests 代码方式执行其它请求方式。当然,它们工作在 s 模式。
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage('s')
+# 获取内置的 Session 对象
+session = page.session
+# 以 head 方式发送请求
+response = session.head('https://www.baidu.com')
+print(response.headers)
+```
+
+输出:
+
+```shell
+{'Accept-Ranges': 'bytes', 'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Length': '277', 'Content-Type': 'text/html', 'Date': 'Tue, 04 Jan 2022 06:49:18 GMT', 'Etag': '"575e1f72-115"', 'Last-Modified': 'Mon, 13 Jun 2016 02:50:26 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18'}
+```
diff --git a/docs/WebPage使用方法/3.3查找元素.md b/docs/WebPage使用方法/3.3查找元素.md
new file mode 100644
index 0000000..204fd76
--- /dev/null
+++ b/docs/WebPage使用方法/3.3查找元素.md
@@ -0,0 +1,708 @@
+本节介绍如何获取元素对象。
+
+无论是数据采集还是页面自动化,定位元素都是重中之重的的技能,浏览器开发者工具虽然可以直接复制绝对 xpath 或 css 路径,但这样做一来代码繁琐,可读性低,二来难以应付动态变化的页面。  
+本库提供一套简洁易用的语法,用于快速定位元素,并且内置等待功能、支持链式查找,减少了代码的复杂性。
+
+定位元素大致分为三种方法:
+
+- 在页面或元素内查找子元素
+- 根据 DOM 结构相对定位
+- 根据页面布局位置相对定位
+
+d 模式的元素还有专门用于处理 shadow dom 的`shadow_root`属性。获取到的元素可继续用这些方法获取后代元素,使用方法和普通元素一致。
+
+# ✔️ 示例
+
+## 📍 简单示例
+
+```html
+<html>
+<body>
+<div id="one">
+    <p class="p_cls" name="row1">第一行</p>
+    <p class="p_cls" name="row2">第二行</p>
+    <p class="p_cls">第三行</p>
+</div>
+<div id="two">
+    第二个div
+</div>
+</body>
+</html>
+```
+
+假设 page 为以上页面的`WebPage`对象,我们可以用这些方法获取其中的元素:
+
+```python
+# 获取 id 为 one 的元素
+div1 = page.ele('#one')
+
+# 获取 div1 元素内所有 p 元素组成的列表
+p_eles = div1.eles('tag:p')
+
+# 获取 name 属性为 row1 的元素
+p1 = page.ele('@name=row1')
+
+# 获取 name 属性为 row2 且包含“第二”文本的 p 元素
+p_ele = page.ele('tag:p@@text():第二@@name=row2')
+
+# 获取包含“第二个div”文本的元素
+div2 = page.ele('第二个div')
+
+# 用 xpath 查找
+div2 = page.ele('xpath://div[@id="tow"]')
+
+# 从第一行元素用相对定位获取第三行元素
+p3 = p1.next(2)
+
+# 获取 p1 元素的父元素
+parent = p1.parent()
+
+# 获取 p1 后面的第一个 div 元素
+div2 = p1.after(1, 'tag:div')
+```
+
+## 📍 实际示例
+
+复制此代码可直接运行查看结果。
+
+```python
+from DrissionPage import WebPage
+
+page = WebPage('s')
+page.get('https://gitee.com/explore')
+
+# 获取包含“全部推荐项目”文本的 ul 元素
+ul_ele = page.ele('tag:ul@@text():全部推荐项目')  
+
+# 获取该 ul 元素下所有 a 元素
+titles = ul_ele.eles('tag:a')  
+
+# 遍历列表,打印每个 a 元素的文本
+for i in titles:  
+    print(i.text)
+
+"""输出:
+全部推荐项目
+前沿技术
+智能硬件
+IOT/物联网/边缘计算
+车载应用
+以下省略……
+"""
+```
+
+# ✔️ 查找元素方法
+
+以下方法,既可用于在页面中查找元素,也可用于在元素中查找子元素。
+
+## ele()
+
+此方法用于查找并返回第一个匹配的元素,d 模式下返回`ChromiumElement`,s 模式下返回`SessionElement`,用 xpath 获取元素属性时,直接返回属性文本。查找不到结果则返回`None`。
+
+参数:
+
+- loc_or_str(元素对象拥有):元素的定位信息,可以是 loc 元组,或查询字符串
+- loc_or_ele(页面对象拥有):元素的定位信息,可以是元素对象,loc 元组,或查询字符串
+- timeout:查找元素超时时间,默认与元素所在页面等待时间一致,s 模式下无效
+
+返回:s 模式下返回`SessionElement`,d 模式下返回`DriverElement`,或用 xpath 获取到的属性值
+
+```python
+# 在页面内查找元素
+ele1 = page.ele('search text')
+
+# 在元素内查找后代元素
+ele2 = ele1.ele('search text')
+
+
+# 使用 xpath 获取后代中第一个 div 元素的 class 属性
+class = ele1.ele('xpath://div/@class')
+```
+
+## eles()
+
+此方法与`ele()`相似,但返回的是匹配到的所有元素组成的列表,用 xpath 获取元素属性时,返回属性文本组成的列表。
+
+参数:
+
+- loc_or_str:元素的定位信息,可以是 loc 元组,或查询字符串
+- timeout:查找元素超时时间,默认与元素所在页面等待时间一致,s 模式下无效
+
+返回:s 模式下返回`SessionElement`组成的列表,d 模式下返回`DriverElement`组成的列表,或用 xpath 获取到的属性值组成的列表
+
+```python
+# 获取 ele 元素内的所有 p 元素
+p_eles = ele.eles('tag:p')
+# 打印第一个 p 元素
+print(p_eles[0])  
+```
+
+## s_ele()
+
+此方法用于在一个元素下查找后代元素,以`SessionElement`形式返回结果(xpath 获取属性值时依然是返回`str`),也可以直接将一个元素或页面转换为`SessionElement`版本。
+
+这是为了 d 模式处理速度的提升,当爬取复杂页面信息而且不须要和元素进行交互时,生成整个页面或者主要容器元素的`SessionElement`,再在其中获取信息,可以将速度提升几个数量级。
+
+s 模式下这个方法和`ele()`是一样的。
+
+参数:
+
+- loc_or_str(元素对象拥有):元素的定位信息,可以是 loc 元组,或查询字符串。为`None`时直接返回当前元素的`SessionElemnet`版本
+- loc_or_ele(页面对象拥有):元素的定位信息,可以是 loc 元组,或查询字符串。为`None`时直接返回当前页面的 `SessionElemnet`版本
+
+返回:`SessionElement`,或用 xpath 获取到的属性值
+
+```python
+# 获取元素或页面的的 SessionElement 版本
+ele2 = ele1.s_ele()
+ele2 = page.s_ele()
+
+# 在 ele1 元素下查找元素,并以 SessionElemnet 返回
+ele2 = ele1.s_ele('search text')
+
+# 在页面下查找元素,并以 SessionElemnet 返回
+ele = page.s_ele('search text')  
+```
+
+## s_eles()
+
+此方法与`s_ele()`相似,但返回的是匹配到的所有元素组成的列表,或属性值组成的列表。
+
+参数:
+
+- loc_or_str:元素的定位信息,可以是 loc 元组,或查询字符串(必填)
+
+返回:`SessionElement`组成的列表,或用 xpath 获取到的属性值组成的列表
+
+## active_ele
+
+该属性返回当前页面焦点所在元素。d 模式独有。
+
+```python
+ele = page.active_ele
+```
+
+## shadow_root
+
+`DriverElement`元素除了以上方法和属性外,还有`shadow_root`属性,用于获取其内部的 shadow_root 元素。  
+该属性返回的是一个`ShadowRootElement`,类似于`DriverElement`,功能比`DriverElement`少。但也有`ele()`和`eles()`方法,可直接搜索其下的元素,返回 `DriverElement`
+元素。返回的`DriverElement`和普通的没有区别。
+
+```python
+# 获取一个元素下是 shadow root
+shadow_ele = ele.shadow_root
+# 获取该 shadow root 下的一个元素
+ele1 = shadow_ele.ele('search text')
+# 点击获取到的元素
+ele1.click()  
+```
+
+# ✔️ 查找语法
+
+我们使用一套简洁高效的语法去定位元素,大大简化了定位元素的代码量,增强了功能,也兼容 css selector、xpath、selenium 原生的 loc 元组(s 模式也能用)。d 模式和 s
+模式定位元素的语法是完全一样的,便于模式切换时平滑过渡。
+
+**匹配模式** 指字符串是否完全匹配,有以下两种:
+
+## 📍 精确匹配符`=`
+
+表示精确匹配,匹配完全符合的文本或属性。
+
+## 📍 模糊匹配符`:`
+
+表示模糊匹配,匹配含有某个字符串的文本或属性。
+
+**关键字** 是出现在定位语句最左边,用于指明该语句以哪种方式去查找元素,有以下这些:
+
+## 📍 id 匹配符`#`
+
+表示`id`属性,只在语句最前面且单独使用时生效,可配合`=`或`:`。
+
+```python
+# 在页面中查找 id 属性为 ele_id 的元素
+ele1 = page.ele('#ele_id')
+
+# 在 ele1 元素内查找 id 属性包含 ele_id 文本的元素
+ele2 = ele1.ele('#:ele_id')  
+```
+
+## 📍 class 匹配符`.`
+
+表示`class`属性,只在语句最前面且单独使用时生效,可配合`=`或`:`。
+
+```python
+# 查找 class 属性为 ele_class 的元素
+ele2 = ele1.ele('.ele_class')
+
+# 查找 class 属性包含 ele_class 文本的元素
+ele2 = ele1.ele('.:ele_class')  
+```
+
+## 📍 单属性匹配符 `@`
+
+表示某个属性,只匹配一个属性。  
+`@`关键字只有一个简单功能,就是匹配`@`后面的内容,不再对后面的字符串进行解析。因此即使后面的字符串也存在`@`或`@@`,也作为要匹配的内容对待。
+
+!> **注意:**  
+如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。
+
+```python
+# 查找 name 属性为 ele_name 的元素
+ele2 = ele1.ele('@name=ele_name')
+
+# 查找 name 属性包含 ele_name 文本的元素
+ele2 = ele1.ele('@name:ele_name')
+
+# 查找有 name 属性的元素
+ele2 = ele1.ele('@name')
+
+# 查找没有任何属性的元素
+ele2 = ele1.ele('@')
+
+# 查找 emaile 属性为 abc@def.com 的元素,有多个 @ 也不会重复处理
+ele2 = ele1.ele('@email=abc@def.com')  
+
+# 属性中有特殊字符的情形,匹配abc@def属性等于v的元素
+ele2 = ele1.ele('css:div[abc\@def="v"]')
+```
+
+## 📍 多属性匹配符`@@`
+
+表示某个属性,多属性匹配时使用,个数不限。还能匹配要忽略的元素,匹配文本时也和`@`不一样。  
+`@@`后跟 - 时,表示 not。如:
+
+- `@@-name`表示匹配没有`name`属性的元素
+
+- `@@-name=ele_name`表示匹配`name`属性不为`ele_name`的元素
+
+如有以下情况,不能使用此方式,须改用 xpath 的方式:
+
+- 匹配文本或属性中出现`@@`
+
+- 属性名本身以`-`开头
+
+!> **注意:**  
+如果属性中包含特殊字符,如包含`@`,用这个方式不能正确匹配到,须使用 css selector 方式查找。且特殊字符要用`\`转义。
+
+```python
+# 查找 name 属性为 name 且 class 属性包含 cls 文本的元素
+ele2 = ele1.ele('@@name=name@@class:cls')
+
+# 查找没有 class 属性的元素
+ele2 = ele1.ele('@@-class')
+
+# 查找 name 属性不包含 ele_name 的元素
+ele2 = ele1.ele('@@-name:ele_name')
+```
+
+## 📍 文本匹配符`text`
+
+要匹配的文本,查询字符串如开头没有任何关键字,也表示根据传入的文本作模糊查找。  
+如果元素内有多个直接的文本节点,精确查找时可匹配所有文本节点拼成的字符串,模糊查找时可匹配每个文本节点。
+
+```python
+# 查找文本为 some text 的元素
+ele2 = ele1.ele('text=some text')
+
+# 查找文本包含 some text 的元素
+ele2 = ele1.ele('text:some text')
+
+# 与上一行一致
+ele2 = ele1.ele('some text')  
+```
+
+?> **Tips:** <br>若要查找的文本包含`text:` ,可下面这样写,即第一个`text:` 为关键字,第二个是要查找的内容:
+
+```python
+ele2 = page.ele('text:text:')
+```
+
+## 📍 文本匹配符`text()`
+
+作为查找属性时使用的文本关键字,必须与`@`或`@@`配合使用。  
+与`@`配合和与`@@`配合使用时,`text()`的意义是有差别的。
+
+`@text()`表示在元素的直接子文本节点中匹配,且多个节点不能合并匹配。 `@@text()`表示在元素内部所有文本中匹配,且会把元素内部所有文本拼成一个总字符串再进行匹配,因此可以模糊匹配元素里面任意文本。
+
+```python
+# 查找文本为 some text 的元素
+ele2 = ele1.ele('@text()=some text')
+
+# 查找文本包含 some text 的元素
+ele2 = ele1.ele('@text():some text')
+
+# 查找文本为 some text 且 class 属性为 cls 的元素
+ele2 = ele1.ele('@@text()=some text@@class=cls')
+
+# 查找文本为 some text 且没有任何属性的元素(因第一个 @@ 后为空)
+ele2 = ele1.ele('@@@@text():some text')
+
+# 查找直接子文本包含 some text 字符串的元素,和 text 关键字没有区别
+ele = page.ele('@text():some text')
+ele = page.ele('text:some text')
+
+# 查找元素内部包含 some text 字符串的元素
+ele = page.ele('@@text():some text')
+```
+
+## 📍 类型匹配符`tag`
+
+表示元素的标签,只在语句最前面且单独使用时生效,可与`@`或`@@`配合使用。`tag:`与`tag=`效果一致。
+
+```python
+# 定位 div 元素
+ele2 = ele1.ele('tag:div')
+
+# 定位 class 属性为 cls 的 div 元素
+ele2 = ele1.ele('tag:div@class=cls')
+
+# 定位文本为 text 的 div 元素
+ele2 = ele1.ele('tag:div@text()=text')
+
+# 定位 class 属性为 cls 且文本为 text 的 div 元素
+ele2 = ele1.ele('tag:div@@class=cls@@text()=text')
+
+# 查找直接文本节点包含 text 字符串的 div 元素
+ele2 = ele1.ele('tag:div@text():text')
+
+# 查找内部文本节点包含 text 字符串的 div 元素
+ele2 = ele1.ele('tag:div@@text():text')  
+```
+
+?> **Tips:** <br>
+注意, `tag:div@text():text` 和 `tag:div@@text():text` 是有区别的,前者只在`div`的直接文本节点搜索,后者搜索`div`的整个内部。
+
+## 📍 css selector 匹配符`css`
+
+表示用 css selector 方式查找元素。`css:`与`css=`效果一致。
+
+```python
+# 查找 div 元素
+ele2 = ele1.ele('css:.div')
+
+# 查找 div 子元素元素,这个写法是本库特有,原生不支持
+ele2 = ele1.ele('css:>div')  
+```
+
+## 📍 xpath 匹配符`xpath`
+
+表示用 xpath 方式查找元素。`xpath:`与`xpath=`效果一致。  
+该方法支持完整的 xpath 语法,能使用 xpath 直接获取元素属性,selenium 不支持这种用法。
+
+```python
+# 查找 div 元素
+ele2 = ele1.ele('xpath:.//div')
+
+# 和上面一行一样,查找元素的后代时,// 前面的 . 可以省略
+ele2 = ele1.ele('xpath://div')
+
+# 获取 div 元素的 class 属性,返回字符串
+txt = ele1.ele('xpath://div/@class')  
+```
+
+?> **Tips:**   <br>
+查找元素的后代时,selenium 原生代码要求 xpath 前面必须加`.`,否则会变成在全个页面中查找。笔者觉得这个设计是画蛇添足,既然已经通过元素查找了,自然应该只查找这个元素内部的元素。所以,用 xpath
+在元素下查找时,最前面`//`或`/`前面的`.`可以省略。
+
+## 📍 selenium 的 loc 元组
+
+查找方法能直接接收 selenium 原生定位元组进行查找,s 模式下也支持这种写法。
+
+```python
+from selenium.webdriver.common.by import By
+
+# 查找 id 为 ele_id 的元素
+loc1 = (By.ID, 'ele_id')
+ele = page.ele(loc1)
+
+# 按 xpath 查找
+loc2 = (By.XPATH, '//div[@class="ele_class"]'
+ele = page.ele(loc2)  
+```
+
+# ✔️ 等待
+
+d 模式下所有查找元素操作都自带等待,默认为跟随元素所在页面`timeout`属性(默认 10 秒),也可以在每次查找时单独设置,单独设置的等待时间不会改变页面原来设置。
+
+```python
+# 页面初始化时设置查找元素超时时间为 15 秒
+page = MixPage(timeout=15)
+# 设置查找元素超时时间为 5 秒
+page.timeout = 5
+
+# 使用页面超时时间来查找元素(5 秒)
+ele1 = page.ele('some text')
+# 为这次查找页面独立设置等待时间(1 秒)
+ele1 = page.ele('some text', timeout=1)
+# 查找后代元素,使用页面超时时间(5 秒)
+ele2 = ele1.ele('some text')
+# 查找后代元素,使用单独设置的超时时间(1 秒)
+ele2 = ele1.ele('some text', timeout=1)  
+```
+
+# ✔️ 相对定位
+
+以下方法可以以某元素为基准,在 DOM 中按照条件获取其兄弟元素、祖先元素、文档前后元素。  
+除获取元素外,还能通过 xpath 获取任意节点内容,如文本节点、注释节点。这在处理元素和文本节点混排的时候非常有用。
+
+## parent()
+
+此方法获取当前元素某一级父元素,可指定筛选条件或层数。
+
+参数:
+
+- level_or_loc:第几级父元素,或定位符
+
+返回:
+
+```python
+# 获取 ele1 的第二层父元素
+ele2 = ele1.parent(2)
+
+# 获取 ele1 父元素中 id 为 id1 的元素
+ele2 = ele1.parent('#id1')
+```
+
+## next()
+
+此方法返回当前元素后面的某一个兄弟元素,可指定筛选条件和第几个。
+
+参数:
+
+- index:查询结果中的第几个
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素后面某个兄弟元素或节点文本
+
+```python
+# 获取 ele1 后面第一个兄弟元素
+ele2 = ele1.next()
+
+# 获取 ele1 后面第 3 个兄弟元素
+ele2 = ele1.next(3)
+
+# 获取 ele1 后面第 3 个 div 兄弟元素
+ele2 = ele1.next(3, 'tag:div')
+
+# 获取 ele1 后面第一个文本节点的文本
+txt = ele1.next(1, 'xpath:text()')
+```
+
+## nexts()
+
+此方法返回后面全部符合条件的兄弟元素或节点组成的列表,可用查询语法筛选。
+
+参数:
+
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素前面符合条件的兄弟元素或节点文本组成的列表
+
+```python
+# 获取 ele1 后面所有兄弟元素
+eles = ele1.nexts()
+
+# 获取 ele1 后面所有 div 兄弟元素
+divs = ele1.nexts('tag:div')
+
+# 获取 ele1 后面的所有文本节点
+txts = ele1.nexts('xpath:text()')
+```
+
+## prev()
+
+此方法返回当前元素前面的某一个兄弟元素,可指定筛选条件和第几个。
+
+参数:
+
+- index:查询结果中的第几个
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素前面某个兄弟元素或节点文本
+
+```python
+# 获取 ele1 前面第一个兄弟元素
+ele2 = ele1.prev()
+
+# 获取 ele1 前面第 3 个兄弟元素
+ele2 = ele1.prev(3)
+
+# 获取 ele1 前面第 3 个 div 兄弟元素
+ele2 = ele1.prev(3, 'tag:div')
+
+# 获取 ele1 前面第一个文本节点的文本
+txt = ele1.prev(1, 'xpath:text()')
+```
+
+## prevs()
+
+此方法返回前面全部符合条件的兄弟元素或节点组成的列表,可用查询语法筛选。
+
+参数:
+
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素前面符合条件的兄弟元素或节点文本组成的列表
+
+```python
+# 获取 ele1 前面所有兄弟元素
+eles = ele1.prevs()
+
+# 获取 ele1 前面所有 div 兄弟元素
+divs = ele1.prevs('tag:div')
+```
+
+## after()
+
+此方法返回当前元素后面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
+
+参数:
+
+- index:查询结果中的第几个
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素后面某个元素或节点
+
+```python
+# 获取 ele1 后面第 3 个元素
+ele2 = ele1.after(3)
+
+# 获取 ele1 后面第 3 个 div 元素
+ele2 = ele1.after(3, 'tag:div')
+
+# 获取 ele1 后面第一个文本节点的文本
+txt = ele1.after(1, 'xpath:text()')
+```
+
+## afters()
+
+此方法返回后面符合条件的全部元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
+
+参数:
+
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素后面符合条件的元素或节点组成的列表
+
+```python
+# 获取 ele1 后所有元素
+eles = ele1.afters()
+
+# 获取 ele1 前面所有 div 元素
+divs = ele1.afters('tag:div')
+```
+
+## before()
+
+此方法返回当前元素前面的某一个元素,可指定筛选条件和第几个。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
+
+参数:
+
+- index:查询结果中的第几个
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素前面某个元素或节点
+
+```python
+# 获取 ele1 前面第 3 个元素
+ele2 = ele1.before(3)
+
+# 获取 ele1 前面第 3 个 div 元素
+ele2 = ele1.before(3, 'tag:div')
+
+# 获取 ele1 前面第一个文本节点的文本
+txt = ele1.before(1, 'xpath:text()')
+```
+
+## befores()
+
+此方法返回前面全部符合条件的元素或节点组成的列表,可用查询语法筛选。这个方法查找范围不局限在兄弟元素间,而是整个 DOM 文档。
+
+参数:
+
+- filter_loc:用于筛选元素的查询语法
+- timeout:查找元素的超时时间
+
+返回:本元素前面符合条件的元素或节点组成的列表
+
+```python
+# 获取 ele1 前面所有元素
+eles = ele1.befores()
+
+# 获取 ele1 前面所有 div 元素
+divs = ele1.befores('tag:div')
+```
+
+# ✔️ `ShadowRootElement`相关查找
+
+本库把 shadow-root 也作为元素对象看待,是为`ShadowRootElement`对象。对`ShadowRootElement`对象可与普通元素一样查找下级元素和 DOM 内相对定位,但不能用页面布局相对定位。  
+对`ShadowRootElement`对象进行相对定位时,把它看作其父对象内部的第一个对象,其余定位逻辑与普通对象一致。
+
+!> **注意:**  <br>
+如果`ShadowRootElement`元素的下级元素中有其它`ShadowRootElement`元素,那这些下级`ShadowRootElement`
+元素内部是无法直接通过定位语句查找到的,只能先定位到其父元素,再用`shadow-root`属性获取。
+
+```python
+# 获取一个 shadow-root 元素
+sr_ele = page.ele('#app').shadow_root
+
+# 在该元素下查找下级元素
+ele1 = sr_ele.ele('tag:div')
+
+# 用相对定位获取其它元素
+ele1 = sr_ele.parent(2)
+ele1 = sr_ele.next(1, 'tag:div')
+ele1 = sr_ele.after(1, 'tag:div')
+eles = sr_ele.nexts('tag:div')
+
+# 定位下级元素中的 shadow+-root 元素
+sr_ele2 = sr_ele.ele('tag:div').shadow_root
+```
+
+# ✔️ 简化写法
+
+为进一步精简代码,对语法进行了精简
+
+- 定位语法都有其简化形式。
+- 页面和元素对象都实现了`__call__()`方法,可直接调用。
+- 所有查找方法都支持链式操作
+
+示例:
+
+```python
+# 定位到页面中 id 为 table_id 的元素,然后获取它的所有 tr 元素
+eles = page('#table_id').eles('t:tr')
+
+# 定位到 class 为 cls 的元素,然后在它里面查找文本为 text 的元素
+ele2 = ele1('.cls1')('tx=text')
+
+# 获取 ele1 的 shadow_root 元素,再在里面查找 class 属性为 cls 的元素
+ele2 = ele1.sr('.cls')
+
+# 按xpath 查找元素
+ele2 = ele1('x://div[@class="ele_class"]')  
+```
+
+简化写法对应列表
+
+| 原写法         | 简化写法 |
+|:-----------:|:----:|
+| text        | tx   |
+| text()      | tx() |
+| tag         | t    |
+| xpath       | x    |
+| css         | c    |
+| shadow_root | sr   |
+
+# Tips
+
+- 从一个`DriverElement`元素获取到的`SessionElement`版本,依然能够使用相对定位方法定位祖先或兄弟元素。
+- `SessionElement`和`SessionPage`的`ele()`和`eles()`方法也有`timeout`参数,但它是不生效的,仅用于保持与 d 模式元素书写一致,便于无差别的调用。
+- 定位语句内容与关键字重复时,请使用 xpath 或 css selector 代替。
diff --git a/docs/_sidebar.md b/docs/_sidebar.md
index 81fc1e8..e94bec1 100644
--- a/docs/_sidebar.md
+++ b/docs/_sidebar.md
@@ -1,48 +1,54 @@
-* [⭐️ 简介](README.md)
+* [⭐️ 1 简介](README.md)
 
-* [🧭 入门指南](#)
-  
-  * [🔥 基本概念](入门指南\基本概念.md)
-  * [👍 快速上手](入门指南\快速上手.md)
-  * [🍀 特性演示](#)
-    * [🌿 与 requests 对比](入门指南\特性演示\与requests代码对比.md)
-    * [🌿 与 selenium 对比](入门指南\特性演示\与selenium代码对比.md)
-    * [🌿 模式切换](入门指南\特性演示\模式切换.md)
-    * [🌿 获取并打印元素属性](入门指南\特性演示\获取并打印元素属性.md)
-    * [🌿 下载文件](入门指南\特性演示\下载文件.md)
+* [🧭 2 入门指南](#)
 
-* [🛠 使用方法](#)
-  
-  * [🔨 创建页面对象](使用方法\创建页面对象.md)
-  * [🔨 访问网页](使用方法\访问网页.md)
-  * [🔨 查找页面元素](使用方法\查找页面元素.md)
-  * [🔨 获取元素信息](使用方法\获取元素信息.md)
-  * [🔨 元素操作](使用方法\元素操作.md)
-  * [🔨 获取网页信息](使用方法\获取网页信息.md)
-  * [🔨 页面操作](使用方法\页面操作.md)
-  * [🔨 启动配置](#)
-    * [🔧 概述](使用方法\启动配置\概述.md)
-    * [🔧 Chrome 启动配置](使用方法\启动配置\Chrome启动配置.md)
-    * [🔧 Session 启动配置](使用方法\启动配置\Session启动配置.md)
-    * [🔧 使用配置文件](使用方法\启动配置\使用配置文件.md)
-  * [🔨 下载文件](使用方法\下载文件.md)
-  * [🔨 监听浏览器网络数据](使用方法\监听浏览器网络数据.md)
-  * [🔨 cookies 的使用](使用方法\cookies的使用.md)
-  * [🔨 Drission 对象](使用方法\Drission对象.md)
-  * [🔨 对接 selenium 及 requests 代码](使用方法\对接selenium及requests代码.md)
-  * [🔨 使用其它系统或浏览器](使用方法\使用其它系统或浏览器.md)
-  * [🔨 DriverPage 和 SessionPage](使用方法\DriverPage和SessionPage.md)
-  * [🔨 打包程序](使用方法\打包程序.md)
+    * [🔥 2.1 基本概念](入门指南\基本概念.md)
+    * [👍 2.2 快速上手](入门指南\快速上手.md)
+    * [🍀 2.3 特性演示](#)
+        * [🌿 与 requests 对比](入门指南\特性演示\与requests代码对比.md)
+        * [🌿 与 selenium 对比](入门指南\特性演示\与selenium代码对比.md)
+        * [🌿 模式切换](入门指南\特性演示\模式切换.md)
+        * [🌿 获取并打印元素属性](入门指南\特性演示\获取并打印元素属性.md)
+        * [🌿 下载文件](入门指南\特性演示\下载文件.md)
 
-* [💖 实用示例](#)
-  
-  * [🧡 自动登录码云](实用示例\自动登录码云.md)
-  * [🧡 获取各国疫情排名](实用示例\获取各国疫情排名.md)
-  * [🧡 下载星巴克产品图片](实用示例\下载星巴克产品图片.md)
-  * [🧡 同时操作多个浏览器](实用示例\同时操作多个浏览器.md)
+* [🛠 3 WebPage 使用方法](#)
 
-* [⚡️ Tips大集合](Tips大集合.md)
+    * [🔨 3.1 创建页面对象](WebPage使用方法\3.1创建页面对象.md)
+    * [🔨 3.2 访问网页](WebPage使用方法\3.2访问网页.md)
+    * [🔨 3.3 查找元素](WebPage使用方法\3.3查找元素.md)
 
-* [🎯️ 版本历史](版本历史.md)
+* [🛠 4 MixPage 使用方法](#)
+
+    * [🔨 4.1 创建页面对象](MixPage使用方法\创建页面对象.md)
+    * [🔨 4.2 访问网页](MixPage使用方法\访问网页.md)
+    * [🔨 4.3 查找页面元素](MixPage使用方法\查找页面元素.md)
+    * [🔨 4.4 获取元素信息](MixPage使用方法\获取元素信息.md)
+    * [🔨 4.5 元素操作](MixPage使用方法\元素操作.md)
+    * [🔨 4.6 获取网页信息](MixPage使用方法\获取网页信息.md)
+    * [🔨 4.7 页面操作](MixPage使用方法\页面操作.md)
+    * [🔨 4.8 启动配置](#)
+        * [🔧 概述](MixPage使用方法\启动配置\概述.md)
+        * [🔧 Chrome 启动配置](MixPage使用方法\启动配置\Chrome启动配置.md)
+        * [🔧 Session 启动配置](MixPage使用方法\启动配置\Session启动配置.md)
+        * [🔧 使用配置文件](MixPage使用方法\启动配置\使用配置文件.md)
+    * [🔨 4.9 下载文件](MixPage使用方法\下载文件.md)
+    * [🔨 4.10 监听浏览器网络数据](MixPage使用方法\监听浏览器网络数据.md)
+    * [🔨 4.11 cookies 的使用](MixPage使用方法\cookies的使用.md)
+    * [🔨 4.12 Drission 对象](MixPage使用方法\Drission对象.md)
+    * [🔨 4.13 对接 selenium 及 requests 代码](MixPage使用方法\对接selenium及requests代码.md)
+    * [🔨 4.14 使用其它系统或浏览器](MixPage使用方法\使用其它系统或浏览器.md)
+    * [🔨 4.15 DriverPage 和 SessionPage](MixPage使用方法\DriverPage和SessionPage.md)
+    * [🔨 4.16 打包程序](MixPage使用方法\打包程序.md)
+
+* [💖 5 实用示例](#)
+
+    * [🧡 自动登录码云](实用示例\自动登录码云.md)
+    * [🧡 获取各国疫情排名](实用示例\获取各国疫情排名.md)
+    * [🧡 下载星巴克产品图片](实用示例\下载星巴克产品图片.md)
+    * [🧡 同时操作多个浏览器](实用示例\同时操作多个浏览器.md)
+
+* [⚡️ 6 Tips大集合](Tips大集合.md)
+
+* [🎯️ 7 版本历史](版本历史.md)
 
 * [💐 鸣谢](鸣谢.md)
diff --git a/setup.py b/setup.py
index 63e1845..aca9951 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.22",
+    version="3.0.23",
     author="g1879",
     author_email="g1879@qq.com",
     description="A module that integrates selenium and requests session, encapsulates common page operations.",