From 171ec15ec05d9bee1095272a7ca8f30fef5c9c7c Mon Sep 17 00:00:00 2001
From: g1879 <g1879@qq.com>
Date: Tue, 28 Dec 2021 18:07:32 +0800
Subject: [PATCH 1/4] =?UTF-8?q?=E5=AE=8C=E5=96=84s=5Fele()=E5=92=8Cs=5Fele?=
 =?UTF-8?q?()=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 DrissionPage/driver_element.py  |  8 ++++----
 DrissionPage/driver_page.py     |  9 ++++++---
 DrissionPage/session_element.py |  6 +++---
 DrissionPage/session_page.py    | 12 ++++++------
 4 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/DrissionPage/driver_element.py b/DrissionPage/driver_element.py
index 23c1e27..4cec864 100644
--- a/DrissionPage/driver_element.py
+++ b/DrissionPage/driver_element.py
@@ -127,14 +127,14 @@ class DriverElement(DrissionElement):
         """
         return self._ele(loc_or_str, timeout=timeout, single=False)
 
-    def s_ele(self, loc_or_ele=None):
+    def s_ele(self, loc_or_str: Union[Tuple[str, str], str] = None):
         """查找第一个符合条件的元素以SessionElement形式返回,处理复杂页面时效率很高        \n
-        :param loc_or_ele: 元素的定位信息,可以是loc元组,或查询字符串
+        :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
         :return: SessionElement对象或属性、文本
         """
-        return make_session_ele(self, loc_or_ele)
+        return make_session_ele(self, loc_or_str)
 
-    def s_eles(self, loc_or_str: Union[Tuple[str, str], str]):
+    def s_eles(self, loc_or_str: Union[Tuple[str, str], str] = None):
         """查找所有符合条件的元素以SessionElement列表形式返回                         \n
         :param loc_or_str: 定位符
         :return: SessionElement或属性、文本组成的列表
diff --git a/DrissionPage/driver_page.py b/DrissionPage/driver_page.py
index 26e4f80..afc4a89 100644
--- a/DrissionPage/driver_page.py
+++ b/DrissionPage/driver_page.py
@@ -112,14 +112,17 @@ class DriverPage(BasePage):
         """
         return self._ele(loc_or_str, timeout, single=False)
 
-    def s_ele(self, loc_or_ele):
+    def s_ele(self, loc_or_ele: Union[Tuple[str, str], str, DriverElement] = None):
         """查找第一个符合条件的元素以SessionElement形式返回,处理复杂页面时效率很高       \n
         :param loc_or_ele: 元素的定位信息,可以是loc元组,或查询字符串
         :return: SessionElement对象或属性、文本
         """
-        return make_session_ele(self, loc_or_ele)
+        if isinstance(loc_or_ele, DriverElement):
+            return make_session_ele(loc_or_ele)
+        else:
+            return make_session_ele(self, loc_or_ele)
 
-    def s_eles(self, loc_or_str: Union[Tuple[str, str], str]):
+    def s_eles(self, loc_or_str: Union[Tuple[str, str], str] = None):
         """查找所有符合条件的元素以SessionElement列表形式返回                       \n
         :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
         :return: SessionElement对象组成的列表
diff --git a/DrissionPage/session_element.py b/DrissionPage/session_element.py
index 60a6366..dbfc857 100644
--- a/DrissionPage/session_element.py
+++ b/DrissionPage/session_element.py
@@ -126,7 +126,7 @@ class SessionElement(DrissionElement):
         """
         return self._ele(loc_or_str)
 
-    def s_eles(self, loc_or_str: Union[Tuple[str, str], str]):
+    def s_eles(self, loc_or_str: Union[Tuple[str, str], str] = None):
         """返回当前元素下级所有符合条件的子元素、属性或节点文本                       \n
         :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
         :return: SessionElement对象或属性、文本组成的列表
@@ -200,9 +200,9 @@ def make_session_ele(html_or_ele: Union[str, BaseElement, BasePage],
     # ---------------处理定位符---------------
     if not loc:
         if isinstance(html_or_ele, SessionElement):
-            return html_or_ele
+            return html_or_ele if single else [html_or_ele]
+
         loc = ('xpath', '.')
-        single = True
 
     elif isinstance(loc, (str, tuple)):
         loc = get_loc(loc)
diff --git a/DrissionPage/session_page.py b/DrissionPage/session_page.py
index 09ad26a..8e2d68d 100644
--- a/DrissionPage/session_page.py
+++ b/DrissionPage/session_page.py
@@ -97,7 +97,7 @@ class SessionPage(BasePage):
 
         return self._url_available
 
-    def ele(self, loc_or_ele: Union[Tuple[str, str], str, SessionElement], timeout=None) \
+    def ele(self, loc_or_ele: Union[Tuple[str, str], str, SessionElement], timeout: float = None) \
             -> Union[SessionElement, List[SessionElement], str, None]:
         """返回页面中符合条件的第一个元素、属性或节点文本                            \n
         :param loc_or_ele: 元素的定位信息,可以是元素对象,loc元组,或查询字符串
@@ -106,7 +106,7 @@ class SessionPage(BasePage):
         """
         return self._ele(loc_or_ele)
 
-    def eles(self, loc_or_str: Union[Tuple[str, str], str], timeout=None) -> List[SessionElement]:
+    def eles(self, loc_or_str: Union[Tuple[str, str], str], timeout: float = None) -> List[SessionElement]:
         """返回页面中所有符合条件的元素、属性或节点文本                          \n
         :param loc_or_str: 元素的定位信息,可以是loc元组,或查询字符串
         :param timeout: 不起实际作用,用于和DriverElement对应,便于无差别调用
@@ -114,14 +114,14 @@ class SessionPage(BasePage):
         """
         return self._ele(loc_or_str, single=False)
 
-    def s_ele(self, loc_or_str: Union[Tuple[str, str], str]):
+    def s_ele(self, loc_or_ele: Union[Tuple[str, str], str, SessionElement] = None):
         """返回页面中符合条件的第一个元素、属性或节点文本                          \n
-        :param loc_or_str: 元素的定位信息,可以是元素对象,loc元组,或查询字符串
+        :param loc_or_ele: 元素的定位信息,可以是元素对象,loc元组,或查询字符串
         :return: SessionElement对象或属性、文本
         """
-        return self._ele(loc_or_str)
+        return make_session_ele(self.html) if loc_or_ele is None else self._ele(loc_or_ele)
 
-    def s_eles(self, loc_or_str: Union[Tuple[str, str], str]):
+    def s_eles(self, loc_or_str: Union[Tuple[str, str], str] = None):
         """返回页面中符合条件的所有元素、属性或节点文本                              \n
         :param loc_or_str: 元素的定位信息,可以是元素对象,loc元组,或查询字符串
         :return: SessionElement对象或属性、文本

From 30b17602ff7a18301fb8c48999f518c38c6900de Mon Sep 17 00:00:00 2001
From: g1879 <g1879@qq.com>
Date: Wed, 29 Dec 2021 15:51:48 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E5=BE=AE=E8=B0=83=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 DrissionPage/base.py | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/DrissionPage/base.py b/DrissionPage/base.py
index 4930a9c..cf00017 100644
--- a/DrissionPage/base.py
+++ b/DrissionPage/base.py
@@ -143,7 +143,7 @@ class DrissionElement(BaseElement):
         :param index: 前面第几个查询结果元素
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: 兄弟元素
+        :return: 兄弟元素或节点文本组成的列表
         """
         nodes = self._get_brothers(index, filter_loc, 'preceding', timeout=timeout)
         return nodes[-1] if nodes else None
@@ -153,7 +153,7 @@ class DrissionElement(BaseElement):
         :param index: 后面第几个查询结果元素
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: 兄弟元素
+        :return: 兄弟元素或节点文本组成的列表
         """
         nodes = self._get_brothers(index, filter_loc, 'following', timeout=timeout)
         return nodes[0] if nodes else None
@@ -162,7 +162,7 @@ class DrissionElement(BaseElement):
         """返回后面全部兄弟元素或节点组成的列表,可用查询语法筛选        \n
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: SessionElement对象
+        :return: 兄弟元素或节点文本组成的列表
         """
         return self._get_brothers(filter_loc=filter_loc, direction='following', timeout=timeout)
 
@@ -170,7 +170,7 @@ class DrissionElement(BaseElement):
         """返回前面全部兄弟元素或节点组成的列表,可用查询语法筛选        \n
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: SessionElement对象
+        :return: 兄弟元素或节点文本组成的列表
         """
         return self._get_brothers(filter_loc=filter_loc, direction='preceding', timeout=timeout)
 
@@ -179,7 +179,7 @@ class DrissionElement(BaseElement):
         :param index: 前面第几个查询结果元素
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: 兄弟元素
+        :return: 本元素前面的某个元素或节点
         """
         nodes = self._get_brothers(index, filter_loc, 'preceding', False, timeout=timeout)
         return nodes[-1] if nodes else None
@@ -189,7 +189,7 @@ class DrissionElement(BaseElement):
         :param index: 后面第几个查询结果元素
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: 兄弟元素
+        :return: 本元素后面的某个元素或节点
         """
         nodes = self._get_brothers(index, filter_loc, 'following', False, timeout)
         return nodes[0] if nodes else None
@@ -198,7 +198,7 @@ class DrissionElement(BaseElement):
         """返回后面全部兄弟元素或节点组成的列表,可用查询语法筛选        \n
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: SessionElement对象
+        :return: 本元素前面的元素或节点组成的列表
         """
         return self._get_brothers(filter_loc=filter_loc, direction='preceding', brother=False, timeout=timeout)
 
@@ -206,7 +206,7 @@ class DrissionElement(BaseElement):
         """返回前面全部兄弟元素或节点组成的列表,可用查询语法筛选        \n
         :param filter_loc: 用于筛选元素的查询语法
         :param timeout: 查找元素的超时时间
-        :return: SessionElement对象
+        :return: 本元素后面的元素或节点组成的列表
         """
         return self._get_brothers(filter_loc=filter_loc, direction='following', brother=False, timeout=timeout)
 

From c4ae8f4a036731764b69ce3cb922eb0481a3e9b5 Mon Sep 17 00:00:00 2001
From: g1879 <g1879@qq.com>
Date: Wed, 29 Dec 2021 16:20:55 +0800
Subject: [PATCH 3/4] 2.2.0

---
 setup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index dde6449..9afac7d 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="2.0.3",
+    version="2.2.0",
     author="g1879",
     author_email="g1879@qq.com",
     description="A module that integrates selenium and requests session, encapsulates common page operations.",

From b363dfccdfa1df21cd6f24e91b3aba5e86d72bd3 Mon Sep 17 00:00:00 2001
From: g1879 <g1879@qq.com>
Date: Thu, 30 Dec 2021 13:10:34 +0800
Subject: [PATCH 4/4] =?UTF-8?q?2.2.1=E3=80=82set=5Fpaths()=E5=A2=9E?=
 =?UTF-8?q?=E5=8A=A0local=5Fport=E5=8F=82=E6=95=B0=EF=BC=9Bini=E6=96=87?=
 =?UTF-8?q?=E4=BB=B6=E7=9A=84=E9=BB=98=E8=AE=A4=E5=8F=82=E6=95=B0=E6=94=B9?=
 =?UTF-8?q?=E6=88=90=E9=BB=98=E8=AE=A4=E7=94=A8=E6=9C=AC=E5=9C=B09222?=
 =?UTF-8?q?=E7=AB=AF=E5=8F=A3=E6=89=93=E5=BC=80=E6=B5=8F=E8=A7=88=E5=99=A8?=
 =?UTF-8?q?=EF=BC=9B=E4=BF=AE=E5=A4=8D=E7=9B=B8=E5=AF=B9=E5=AE=9A=E4=BD=8D?=
 =?UTF-8?q?=E7=9A=84=E4=B8=80=E4=B8=AA=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 DrissionPage/base.py     | 2 +-
 DrissionPage/config.py   | 5 +++++
 DrissionPage/configs.ini | 2 +-
 DrissionPage/easy_set.py | 7 ++++++-
 setup.py                 | 2 +-
 5 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/DrissionPage/base.py b/DrissionPage/base.py
index cf00017..46b76a3 100644
--- a/DrissionPage/base.py
+++ b/DrissionPage/base.py
@@ -239,7 +239,7 @@ class DrissionElement(BaseElement):
             loc = loc[1].lstrip('./')
 
         if index:
-            loc = f'xpath:(./{direction}{brother}::{loc})[{index}]'  # TODO: 有没有括号是否有区别
+            loc = f'xpath:./{direction}{brother}::{loc}[{index}]'
         else:
             loc = f'xpath:./{direction}{brother}::{loc}'
 
diff --git a/DrissionPage/config.py b/DrissionPage/config.py
index f16f30f..33d6cfc 100644
--- a/DrissionPage/config.py
+++ b/DrissionPage/config.py
@@ -599,6 +599,7 @@ class DriverOptions(Options):
     def set_paths(self,
                   driver_path: str = None,
                   chrome_path: str = None,
+                  local_port: Union[int, str] = None,
                   debugger_address: str = None,
                   download_path: str = None,
                   user_data_path: str = None,
@@ -606,6 +607,7 @@ class DriverOptions(Options):
         """快捷的路径设置函数                                             \n
         :param driver_path: chromedriver.exe路径
         :param chrome_path: chrome.exe路径
+        :param local_port: 本地端口号
         :param debugger_address: 调试浏览器地址,例:127.0.0.1:9222
         :param download_path: 下载文件路径
         :param user_data_path: 用户数据路径
@@ -618,6 +620,9 @@ class DriverOptions(Options):
         if chrome_path is not None:
             self.binary_location = chrome_path
 
+        if local_port is not None:
+            self.debugger_address = f'127.0.0.1:{local_port}'
+
         if debugger_address is not None:
             self.debugger_address = debugger_address
 
diff --git a/DrissionPage/configs.ini b/DrissionPage/configs.ini
index 21eee64..f5c629d 100644
--- a/DrissionPage/configs.ini
+++ b/DrissionPage/configs.ini
@@ -3,7 +3,7 @@ chromedriver_path =
 tmp_path =
 
 [chrome_options]
-debugger_address =
+debugger_address = 127.0.0.1:9222
 binary_location =
 arguments = ['--no-sandbox', '--disable-gpu', '--ignore-certificate-errors', '--disable-infobars']
 extensions = []
diff --git a/DrissionPage/easy_set.py b/DrissionPage/easy_set.py
index 070ab50..04cc4e1 100644
--- a/DrissionPage/easy_set.py
+++ b/DrissionPage/easy_set.py
@@ -31,6 +31,7 @@ def show_settings(ini_path: str = None) -> None:
 
 def set_paths(driver_path: str = None,
               chrome_path: str = None,
+              local_port: Union[int, str] = None,
               debugger_address: str = None,
               tmp_path: str = None,
               download_path: str = None,
@@ -41,6 +42,7 @@ def set_paths(driver_path: str = None,
     """快捷的路径设置函数                                          \n
     :param driver_path: chromedriver.exe路径
     :param chrome_path: chrome.exe路径
+    :param local_port: 本地端口号
     :param debugger_address: 调试浏览器地址,例:127.0.0.1:9222
     :param download_path: 下载文件路径
     :param tmp_path: 临时文件夹路径
@@ -53,7 +55,7 @@ def set_paths(driver_path: str = None,
     om = OptionsManager(ini_path)
 
     def format_path(path: str) -> str:
-        return '' if not path else str(path).replace('/', '\\')
+        return path or ''
 
     if driver_path is not None:
         om.set_item('paths', 'chromedriver_path', format_path(driver_path))
@@ -61,6 +63,9 @@ def set_paths(driver_path: str = None,
     if chrome_path is not None:
         om.set_item('chrome_options', 'binary_location', format_path(chrome_path))
 
+    if local_port is not None:
+        om.set_item('chrome_options', 'debugger_address', format_path(f'127.0.0.1:{local_port}'))
+
     if debugger_address is not None:
         om.set_item('chrome_options', 'debugger_address', format_path(debugger_address))
 
diff --git a/setup.py b/setup.py
index 9afac7d..e84ed03 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="2.2.0",
+    version="2.2.1",
     author="g1879",
     author_email="g1879@qq.com",
     description="A module that integrates selenium and requests session, encapsulates common page operations.",