diff --git a/DrissionPage/action_chains.py b/DrissionPage/action_chains.py index 3c6d40c..11694f0 100644 --- a/DrissionPage/action_chains.py +++ b/DrissionPage/action_chains.py @@ -23,9 +23,9 @@ class ActionChains: self.curr_y = 0 def move_to(self, ele_or_loc, offset_x=0, offset_y=0): - """鼠标移动到元素中点,或页面上的某个绝对坐标。可设置偏移量 \n + """鼠标移动到元素中点,或页面上的某个绝对坐标。可设置偏移量 \n 当带偏移量时,偏移量相对于元素左上角坐标 - :param ele_or_loc: 元素对象或绝对坐标,坐标为tuple(int, int)形式 + :param ele_or_loc: 元素对象、绝对坐标或文本定位符,坐标为tuple(int, int)形式 :param offset_x: 偏移量x :param offset_y: 偏移量y :return: self @@ -33,7 +33,8 @@ class ActionChains: if isinstance(ele_or_loc, (tuple, list)): lx = ele_or_loc[0] + offset_x ly = ele_or_loc[1] + offset_y - elif 'ChromiumElement' in str(type(ele_or_loc)): + elif isinstance(ele_or_loc, str) or 'ChromiumElement' in str(type(ele_or_loc)): + ele_or_loc = self.page(ele_or_loc) x, y = ele_or_loc.location if offset_x or offset_y else ele_or_loc.midpoint lx = x + offset_x ly = y + offset_y @@ -60,51 +61,111 @@ class ActionChains: self._dr.Input.dispatchMouseEvent(type='mouseMoved', x=self.curr_x, y=self.curr_y, modifiers=self.modifier) return self - def hold(self, on_ele=None): - """点击并按住当前坐标或指定元素 \n - :param on_ele: ChromiumElement对象 - :return: self - """ - if on_ele: - self.move_to(on_ele) - self._dr.Input.dispatchMouseEvent(type='mousePressed', button='left', - x=self.curr_x, y=self.curr_y, modifiers=self.modifier) - return self - def click(self, on_ele=None): - """点击鼠标左键,可先移动到元素上 \n - :param on_ele: ChromiumElement元素 + """点击鼠标左键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 :return: self """ if on_ele: self.move_to(on_ele) - self._dr.Input.dispatchMouseEvent(type='mousePressed', button='left', - x=self.curr_x, y=self.curr_y, modifiers=self.modifier) - self._dr.Input.dispatchMouseEvent(type='mouseReleased', button='left', - x=self.curr_x, y=self.curr_y, modifiers=self.modifier) + self._hold('left').wait(.05)._release('left') return self def r_click(self, on_ele=None): - """点击鼠标右键,可先移动到元素上 \n - :param on_ele: ChromiumElement元素 + """点击鼠标右键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 :return: self """ if on_ele: self.move_to(on_ele) - self._dr.Input.dispatchMouseEvent(type='mousePressed', button='right', - x=self.curr_x, y=self.curr_y, modifiers=self.modifier) - self._dr.Input.dispatchMouseEvent(type='mouseReleased', button='right', - x=self.curr_x, y=self.curr_y, modifiers=self.modifier) + self._hold('right').wait(.05)._release('right') + return self + + def m_click(self, on_ele=None): + """点击鼠标中键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 + :return: self + """ + if on_ele: + self.move_to(on_ele) + self._hold('middle').wait(.05)._release('middle') + return self + + def hold(self, on_ele=None): + """按住鼠标左键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 + :return: self + """ + if on_ele: + self.move_to(on_ele) + self._hold('left') return self def release(self, on_ele=None): - """释放鼠标左键,可先移动到元素再释放 \n - :param on_ele: ChromiumElement对象 + """释放鼠标左键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 :return: self """ if on_ele: self.move_to(on_ele) - self._dr.Input.dispatchMouseEvent(type='mouseReleased', button='left', + self._release('left') + return self + + def r_hold(self, on_ele=None): + """按住鼠标右键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 + :return: self + """ + if on_ele: + self.move_to(on_ele) + self._hold('right') + return self + + def r_release(self, on_ele=None): + """释放鼠标右键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 + :return: self + """ + if on_ele: + self.move_to(on_ele) + self._release('right') + return self + + def m_hold(self, on_ele=None): + """按住鼠标中键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 + :return: self + """ + if on_ele: + self.move_to(on_ele) + self._hold('middle') + return self + + def m_release(self, on_ele=None): + """释放鼠标中键,可先移动到元素上 \n + :param on_ele: ChromiumElement元素或文本定位符 + :return: self + """ + if on_ele: + self.move_to(on_ele) + self._release('middle') + return self + + def _hold(self, button): + """按下鼠标按键 \n + :param button: 要按下的按键 + :return: self + """ + self._dr.Input.dispatchMouseEvent(type='mousePressed', button=button, clickCount=1, + x=self.curr_x, y=self.curr_y, modifiers=self.modifier) + return self + + def _release(self, button): + """释放鼠标按键 \n + :param button: 要释放的按键 + :return: self + """ + self._dr.Input.dispatchMouseEvent(type='mouseReleased', button=button, clickCount=1, x=self.curr_x, y=self.curr_y, modifiers=self.modifier) return self @@ -163,6 +224,17 @@ class ActionChains: self.page.run_cdp('Input.dispatchKeyEvent', **data) return self + def type(self, text): + """输入文本 \n + :param text: 要输入的文本 + :return: self + """ + for i in text: + self.key_down(i) + sleep(.05) + self.key_up(i) + return self + def wait(self, second): """等待若干秒""" sleep(second) diff --git a/DrissionPage/action_chains.pyi b/DrissionPage/action_chains.pyi index b9558d5..4c0d8be 100644 --- a/DrissionPage/action_chains.pyi +++ b/DrissionPage/action_chains.pyi @@ -13,27 +13,41 @@ from .chromium_page import ChromiumPage class ActionChains: - def __init__(self, page:ChromiumBase): + def __init__(self, page: ChromiumBase): self.page: ChromiumPage = ... self._dr: ChromiumDriver = ... self.curr_x: int = ... self.curr_y: int = ... self.modifier: int = ... - def move_to(self, ele_or_loc: Union[ChromiumElement, Tuple[int, int]], + def move_to(self, ele_or_loc: Union[ChromiumElement, Tuple[int, int], str], offset_x: int = ..., offset_y: int = ...) -> ActionChains: ... def move(self, offset_x: int = ..., offset_y: int = ...) -> ActionChains: ... - def hold(self, on_ele:ChromiumElement=...) -> ActionChains: ... + def click(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... - def click(self, on_ele:ChromiumElement=...) -> ActionChains: ... + def r_click(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... - def r_click(self, on_ele:ChromiumElement=...) -> ActionChains: ... + def m_click(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... - def release(self, on_ele:ChromiumElement=...) -> ActionChains: ... + def hold(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... - def scroll(self, delta_x: int = ..., delta_y: int = ..., on_ele:ChromiumElement=...) -> ActionChains: ... + def release(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... + + def r_hold(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... + + def r_release(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... + + def m_hold(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... + + def m_release(self, on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... + + def _hold(self, button: str) -> ActionChains: ... + + def _release(self, button: str) -> ActionChains: ... + + def scroll(self, delta_x: int = ..., delta_y: int = ..., on_ele: Union[ChromiumElement, str] = ...) -> ActionChains: ... def up(self, pixel: int) -> ActionChains: ... @@ -43,13 +57,15 @@ class ActionChains: def right(self, pixel: int) -> ActionChains: ... - def key_down(self, key:str) -> ActionChains: ... + def key_down(self, key: str) -> ActionChains: ... - def key_up(self, key:str) -> ActionChains: ... + def key_up(self, key: str) -> ActionChains: ... + + def type(self, text: str) -> ActionChains: ... def wait(self, second: float) -> ActionChains: ... - def _get_key_data(self, key:str, action: str) -> dict: ... + def _get_key_data(self, key: str, action: str) -> dict: ... def location_to_client(page, lx: int, ly: int) -> tuple: ... diff --git a/DrissionPage/chromium_base.py b/DrissionPage/chromium_base.py index 3ec452c..8241bcb 100644 --- a/DrissionPage/chromium_base.py +++ b/DrissionPage/chromium_base.py @@ -329,12 +329,14 @@ class ChromiumBase(BasePage): :param timeout: 超时时间 :return: 等待结束时是否进入加载状态 """ - end_time = perf_counter() + timeout - while perf_counter() < end_time: - if self.is_loading: - return True - sleep(.005) - return False + if timeout: + timeout = 2 if timeout is True else timeout + end_time = perf_counter() + timeout + while perf_counter() < end_time: + if self.is_loading: + return True + sleep(.005) + return False def get_cookies(self, as_dict=False): """获取cookies信息 \n @@ -363,12 +365,12 @@ class ChromiumBase(BasePage): result_cookies.append(c) self._wait_driver.Network.setCookies(cookies=result_cookies) - # def set_headers(self, headers: dict) -> None: - # """设置固定发送的headers \n - # :param headers: dict格式的headers数据 - # :return: None - # """ - # self.run_cdp('Network.setExtraHTTPHeaders', headers=headers) + def set_headers(self, headers: dict) -> None: + """设置固定发送的headers \n + :param headers: dict格式的headers数据 + :return: None + """ + self.run_cdp('Network.setExtraHTTPHeaders', headers=headers, not_change=True) def ele(self, loc_or_ele, timeout=None): """获取第一个符合条件的元素对象 \n diff --git a/DrissionPage/chromium_element.py b/DrissionPage/chromium_element.py index ff8a247..461aede 100644 --- a/DrissionPage/chromium_element.py +++ b/DrissionPage/chromium_element.py @@ -582,13 +582,13 @@ class ChromiumElement(DrissionElement): else: self.input(('\ue009', 'a', '\ue017'), clear=False) - def click(self, by_js=None, retry=False, timeout=.2, wait_loading=False): + def click(self, by_js=None, retry=False, timeout=.2, wait_loading=0): """点击元素 \n 如果遇到遮挡,会重新尝试点击直到超时,若都失败就改用js点击 \n :param by_js: 是否用js点击,为True时直接用js点击,为False时重试失败也不会改用js :param retry: 遇到其它元素遮挡时,是否重试 :param timeout: 尝试点击的超时时间,不指定则使用父页面的超时时间,retry为True时才生效 - :param wait_loading: 是否等待页面进入加载状态 + :param wait_loading: 等待页面进入加载状态超时时间 :return: 是否点击成功 """ @@ -614,8 +614,7 @@ class ChromiumElement(DrissionElement): click = do_it(client_x, client_y, loc_x, loc_y) if click: - if wait_loading: - self.page.wait_loading() + self.page.wait_loading(wait_loading) return True timeout = timeout if timeout is not None else self.page.timeout @@ -624,14 +623,12 @@ class ChromiumElement(DrissionElement): click = do_it(client_x, client_y, loc_x, loc_y) if click is not None: - if wait_loading: - self.page.wait_loading() + self.page.wait_loading(wait_loading) return True if by_js is not False: self.run_script('this.click();') - if wait_loading: - self.page.wait_loading() + self.page.wait_loading(wait_loading) return True return False @@ -652,6 +649,12 @@ class ChromiumElement(DrissionElement): x, y = self._client_click_point self._click(x, y, 'right') + def m_click(self): + """中键单击""" + self.page.scroll_to_see(self) + x, y = self._client_click_point + self._click(x, y, 'middle') + def r_click_at(self, offset_x=None, offset_y=None): """带偏移量右键单击本元素,相对于左上角坐标。不传入x或y值时点击元素中点 \n :param offset_x: 相对元素左上角坐标的x轴偏移量 @@ -669,7 +672,7 @@ class ChromiumElement(DrissionElement): """ self.page.driver.Input.dispatchMouseEvent(type='mousePressed', x=client_x, y=client_y, button=button, clickCount=1) - sleep(.1) + sleep(.05) self.page.driver.Input.dispatchMouseEvent(type='mouseReleased', x=client_x, y=client_y, button=button) def hover(self, offset_x=None, offset_y=None): diff --git a/DrissionPage/chromium_element.pyi b/DrissionPage/chromium_element.pyi index a0dee99..565de68 100644 --- a/DrissionPage/chromium_element.pyi +++ b/DrissionPage/chromium_element.pyi @@ -204,12 +204,15 @@ class ChromiumElement(DrissionElement): def clear(self, by_js: bool = ...) -> None: ... - def click(self, by_js: bool = ..., retry: bool = ..., timeout: float = ..., wait_loading: bool = ...) -> bool: ... + def click(self, by_js: bool = ..., retry: bool = ..., timeout: float = ..., + wait_loading: Union[bool, float] = ...) -> bool: ... def click_at(self, offset_x: Union[int, str] = ..., offset_y: Union[int, str] = ..., button: str = ...) -> None: ... def r_click(self) -> None: ... + def m_click(self) -> None: ... + def r_click_at(self, offset_x: Union[int, str] = ..., offset_y: Union[int, str] = ...) -> None: ... def _click(self, client_x: int, client_y: int, button: str = ...) -> None: ... diff --git a/DrissionPage/session_page.py b/DrissionPage/session_page.py index 900967f..8d43ba8 100644 --- a/DrissionPage/session_page.py +++ b/DrissionPage/session_page.py @@ -73,6 +73,15 @@ class SessionPage(BasePage): self.session.cookies.set(cookie['name'], cookie['value'], **kwargs) + def set_headers(self, headers): + """设置通用的headers,设置的headers值回逐个覆盖原有的,不会清理原来的 \n + :param headers: dict形式的headers + :return: None + """ + headers = CaseInsensitiveDict(headers) + for i in headers: + self.session.headers[i] = headers[i] + def __call__(self, loc_or_str, timeout=None): """在内部查找元素 \n 例:ele2 = ele1('@id=ele_id') \n diff --git a/DrissionPage/session_page.pyi b/DrissionPage/session_page.pyi index b72c2fc..35e70f8 100644 --- a/DrissionPage/session_page.pyi +++ b/DrissionPage/session_page.pyi @@ -34,6 +34,8 @@ class SessionPage(BasePage): def set_cookies(self, cookies: Union[RequestsCookieJar, list, tuple, str, dict]) -> None: ... + def set_headers(self, headers: dict) -> None: ... + def __call__(self, loc_or_str: Union[Tuple[str, str], str, SessionElement], timeout: float = ...) -> Union[SessionElement, str, None]: ... diff --git a/docs/README.md b/docs/README.md index fbdb2c0..a2a2108 100644 --- a/docs/README.md +++ b/docs/README.md @@ -46,7 +46,7 @@ DrissionPage,即 driver 和 session 组合而成的 page。 3.0 版已经发布,目前正在测试,欢迎试用并提出意见,让我做得更好。 -文档正在更新,目前还是旧版,以后实例主要使用`WebPage`,`MixPage`与其不一致的地方才会说明。 + # 💡 特性和亮点 diff --git a/docs/WebPage使用方法/3.0概述.md b/docs/WebPage使用方法/3.0概述.md new file mode 100644 index 0000000..738944f --- /dev/null +++ b/docs/WebPage使用方法/3.0概述.md @@ -0,0 +1,22 @@ +以前的版本是对 selenium 进行重新封装实现的。从 3.0 开始,作者另起炉灶,对底层进行了重新开发,摆脱对 selenium 的依赖,增强了功能,提升了运行效率。 +3.0 全新开发的页面对象是`WebPage`,支持 chromium 内核的浏览器(如 chrome 和 edge)。除了保持之前的功能,比依赖 selenium 的`MixPage`有以下优点: + +- 无 webdriver 特征,不会被网站识别 + +- 无需为不同版本的浏览器下载不同的驱动 + +- 运行速度更快 + +- 可以跨 iframe 查找元素,无需切入切出 + +- 把 iframe 看作普通元素,获取后可直接在其中查找元素,逻辑更清晰 + +- 可以同时操作浏览器中的多个标签页,即使标签页为非激活状态,无需切换 + +- 可以直接读取浏览器缓存来保存图片,无需用 GUI 点击另存 + +- 可以对整个网页截图,包括视口外的部分(90以上版本浏览器支持) + +- 对 Linux 提供良好支持 + +新版是自己实现的功能,开发不会受太多限制,以后将主要对`WebPage`进行更新。旧版只会修 bug。 diff --git a/docs/WebPage使用方法/3.10动作链.md b/docs/WebPage使用方法/3.10动作链.md index c85c5bc..c3576fe 100644 --- a/docs/WebPage使用方法/3.10动作链.md +++ b/docs/WebPage使用方法/3.10动作链.md @@ -26,7 +26,7 @@ ac = ActionChains(page) **参数:** -- `ele_or_loc`:元素对象或绝对坐标,坐标为`tuple`(int, int) 形式 +- `ele_or_loc`:元素对象、文本定位符或绝对坐标,坐标为`tuple`(int, int) 形式 - `offset_x`:偏移量 x @@ -107,7 +107,7 @@ ac.up(50) # 鼠标向上移动 50 像素 **参数:** -- `on_ele`:`ChromiumElement`元素 +- `on_ele`:`ChromiumElement`元素或文本定位符 **返回:**`ActionChains`对象自己 @@ -117,7 +117,17 @@ ac.up(50) # 鼠标向上移动 50 像素 **参数:** -- `on_ele`:`ChromiumElement`元素 +- `on_ele`:`ChromiumElement`元素或文本定位符 + +**返回:**`ActionChains`对象自己 + +## 📍 `m_click()` + +此方法用于单击鼠标中键,单击前可先移动到元素上。 + +**参数:** + +- `on_ele`:`ChromiumElement`元素或文本定位符 **返回:**`ActionChains`对象自己 @@ -127,7 +137,7 @@ ac.up(50) # 鼠标向上移动 50 像素 **参数:** -- `on_ele`:`ChromiumElement`元素 +- `on_ele`:`ChromiumElement`元素或文本定位符 **返回:**`ActionChains`对象自己 @@ -137,7 +147,47 @@ ac.up(50) # 鼠标向上移动 50 像素 **参数:** -- `on_ele`:`ChromiumElement`元素 +- `on_ele`:`ChromiumElement`元素或文本定位符 + +**返回:**`ActionChains`对象自己 + +## 📍 `r_hold()` + +此方法用于按住鼠标右键不放,按住前可先移动到元素上。 + +**参数:** + +- `on_ele`:`ChromiumElement`元素或文本定位符 + +**返回:**`ActionChains`对象自己 + +## 📍 `r_release()` + +此方法用于释放鼠标右键,释放前可先移动到元素上。 + +**参数:** + +- `on_ele`:`ChromiumElement`元素或文本定位符 + +**返回:**`ActionChains`对象自己 + +## 📍 `m_hold()` + +此方法用于按住鼠标中键不放,按住前可先移动到元素上。 + +**参数:** + +- `on_ele`:`ChromiumElement`元素或文本定位符 + +**返回:**`ActionChains`对象自己 + +## 📍 `m_release()` + +此方法用于释放鼠标中键,释放前可先移动到元素上。 + +**参数:** + +- `on_ele`:`ChromiumElement`元素或文本定位符 **返回:**`ActionChains`对象自己 @@ -151,7 +201,7 @@ ac.up(50) # 鼠标向上移动 50 像素 - `delta_x`:滚轮变化值 x - `delta_y`:滚轮变化值 y -- `on_ele`:`ChromiumElement`元素 +- `on_ele`:`ChromiumElement`元素或文本定位符 **返回:**`ActionChains`对象自己 @@ -183,6 +233,16 @@ ac.key_down(Keys.CTRL) # 按下 ctrl 键 **返回:**`ActionChains`对象自己 +## 📍 `type()` + +此方法用于输入一段文本。 + +**参数:** + +- `text`:文本字符串 + +**返回:**`ActionChains`对象自己 + # ✔ 等待 ## 📍 `wait()` @@ -212,5 +272,3 @@ ac = ActionCHains(page) # 链式操作 ac.move_to('tag:h1').right(30).click().key_down('a').key_up('a') ``` - - diff --git a/docs/WebPage使用方法/3.5元素操作.md b/docs/WebPage使用方法/3.5元素操作.md index f97502b..2bb1ea3 100644 --- a/docs/WebPage使用方法/3.5元素操作.md +++ b/docs/WebPage使用方法/3.5元素操作.md @@ -15,15 +15,14 @@ iframe 元素`ChromiumFrame`使用方法后面章节单独介绍。 此设计除了可保证点击成功,还可以用于检测页面上的遮罩层是否消失。遮罩层经常出现在 js 方式翻页的时候,它的覆盖会阻碍模拟点击,所以可以通过对其下面的元素不断重试点击,来判断遮罩层是否存在。当然,这个方法是否可行要看具体网页设计。 而如果直接使用 js 进行点击,则可无视任何遮挡,只要元素在 DOM 内,就能点击得到,这样可以根据须要灵活地对元素进行操作。 -通常,点击链接后立刻获取新页面的元素,程序可自动等待元素加载,但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。可以把`wait_loading`参数设为`True`,点击后程序会等待页面进入 -loading 状态,才会继续往下执行,从而避免上述问题。 +通常,点击链接后立刻获取新页面的元素,程序可自动等待元素加载,但若跳转前的页面拥有和跳转后页面相同定位符的元素,会导致过早获取元素,跳转后失效的问题。可以把`wait_loading`参数设置一个超时时间,点击后程序会等待页面进入 loading 状态,才会继续往下执行,从而避免上述问题。 **参数:** - `by_js`:是否用 js 方式点击,为`None`时如`retry`为`True`,先用模拟方法点击,重试失败超时后改为用 js 点击;为`True`时直接用 js 点击;为`False`时即使重试超时也不会改用 js - `retry`:遇到其它元素遮挡时,是否重试 - `timeout`:点击失败重试超时时间,为`None`时使用父页面`timeout`设置 -- `wait_loading`:是否等待页面进入加载状态 +- `wait_loading`:等待页面进入加载状态的超时时间,默认 0 **返回:**`bool`,表示是否点击成功。 @@ -92,6 +91,18 @@ ele.r_click() ele.r_click_at(50, 50) ``` +## 📍 `m_click()` + +此方法实现中键单击元素。 + +**参数:** 无 + +**返回:**`None` + +```python +ele.m_click() +``` + # ✔️ 输入内容 ## 📍 `clear()` diff --git a/docs/_sidebar.md b/docs/_sidebar.md index c2f9045..92589d1 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -1,4 +1,4 @@ -* [⭐️ 1 简介](README.md) +* [⭐️ 1 概述](README.md) * [🧭 2 入门指南](#) @@ -14,6 +14,7 @@ * [🛠 3 WebPage 使用方法](#) + * [🔨 3.0 简介](WebPage使用方法\3.0概述.md) * [🔨 3.1 创建页面对象](WebPage使用方法\3.1创建页面对象.md) * [🔨 3.2 访问网页](WebPage使用方法\3.2访问网页.md) * [🔨 3.3 查找元素](WebPage使用方法\3.3查找元素.md) @@ -53,11 +54,12 @@ * [⚙️ 6.2 监听浏览器网络](进阶使用\监听浏览器网络.md) * [⚙️ 6.3 下载文件](进阶使用\下载文件.md) -* [⚡️ 7 实用示例](#) +* [⚡️ 7 示例和技巧](#) * [🌠 自动登录码云](实用示例\自动登录码云.md) * [🌠 采集猫眼电影TOP100榜](实用示例\采集猫眼电影TOP100榜.md) * [🌠 下载星巴克产品图片](实用示例\下载星巴克产品图片.md) + * [🌠 下载豆瓣图书封面图片](实用示例\下载豆瓣图书封面图片.md) * [🌠 多线程操作多标签页](实用示例\多线程操作多标签页.md) * [🔖 9 版本历史](版本历史.md) diff --git a/docs/imgs/20230105105418.png b/docs/imgs/20230105105418.png new file mode 100644 index 0000000..739763a Binary files /dev/null and b/docs/imgs/20230105105418.png differ diff --git a/docs/版本历史.md b/docs/版本历史.md index 26b2531..05369af 100644 --- a/docs/版本历史.md +++ b/docs/版本历史.md @@ -1,3 +1,13 @@ +# v3.0.30 + +- 元素增加`m_click()`方法 + +- 动作链增加`type()`、`m_click()`、`r_hold()`、`r_release()`、`m_hold()`、`m_release()`方法 + +- 动作链的`on_ele`参数可接收文本定位符 + +- `WebPage`、`SessionPage`、`ChromiumPage`增加`set_headers()`方法 + # v3.0.28 - 各种大小、位置信息从`dict`改为用`tuple`返回 @@ -14,7 +24,7 @@ - `change_mode()`增加`copy_cookies`参数 -- ###### 调整`WebPage`生成的元素对象的`prev()`、`next()`、`before()`、`after()`参数顺序 +- 调整`WebPage`生成的元素对象的`prev()`、`next()`、`before()`、`after()`参数顺序 - 修复读取页面时小概率失效问题 @@ -65,10 +75,10 @@ # v2.7.1 - DriverPage - - - 增加`get_session_storage()`、`get_local_storage()`、`set_session_storage()`、`set_local_storage()`、`clean_cache()`方法 - - - `run_cdp()`的`cmd_args`参数改为`**cmd_args` + + - 增加`get_session_storage()`、`get_local_storage()`、`set_session_storage()`、`set_local_storage()`、`clean_cache()`方法 + + - `run_cdp()`的`cmd_args`参数改为`**cmd_args` - 关闭 driver 时会主动关闭 chromedriver.exe 的进程 @@ -82,9 +92,9 @@ # v2.6.0 - 新增`Listener`类 - - 可监听浏览器数据包 - - 可异步监听 - - 可实现每监听到若干数据包执行操作 + - 可监听浏览器数据包 + - 可异步监听 + - 可实现每监听到若干数据包执行操作 - 放弃对selenium4.1以下的支持 - 解决使用新版浏览器时出现的一些问题 diff --git a/docs/实用示例/下载星巴克产品图片.md b/docs/示例和技巧/下载星巴克产品图片.md similarity index 100% rename from docs/实用示例/下载星巴克产品图片.md rename to docs/示例和技巧/下载星巴克产品图片.md diff --git a/docs/实用示例/多线程操作多标签页.md b/docs/示例和技巧/多线程操作多标签页.md similarity index 100% rename from docs/实用示例/多线程操作多标签页.md rename to docs/示例和技巧/多线程操作多标签页.md diff --git a/docs/实用示例/自动登录码云.md b/docs/示例和技巧/自动登录码云.md similarity index 100% rename from docs/实用示例/自动登录码云.md rename to docs/示例和技巧/自动登录码云.md diff --git a/docs/实用示例/采集猫眼电影TOP100榜.md b/docs/示例和技巧/采集猫眼电影TOP100榜.md similarity index 98% rename from docs/实用示例/采集猫眼电影TOP100榜.md rename to docs/示例和技巧/采集猫眼电影TOP100榜.md index 064f54f..8805367 100644 --- a/docs/实用示例/采集猫眼电影TOP100榜.md +++ b/docs/示例和技巧/采集猫眼电影TOP100榜.md @@ -1,6 +1,6 @@ 这个示例演示用浏览器采集数据。 -# ✔️ 页面分析 +# ✔️ 采集目标 目标网址:[https://www.maoyan.com/board/4](https://www.maoyan.com/board/4) diff --git a/setup.py b/setup.py index 113a4c2..51c6c30 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.28", + version="3.0.30", author="g1879", author_email="g1879@qq.com", description="A module that integrates selenium and requests session, encapsulates common page operations.",