ChromiumDirver删除GenericAttr

This commit is contained in:
g1879 2023-07-24 15:42:43 +08:00
parent 0845814dc5
commit cbc9367127
7 changed files with 23 additions and 51 deletions

View File

@ -103,14 +103,14 @@ class ChromiumBase(BasePage):
self._tab_obj = ChromiumDriver(tab_id=tab_id, tab_type='page', address=self.address)
self._tab_obj.start()
self._tab_obj.DOM.enable()
self._tab_obj.Page.enable()
self._tab_obj.call_method('DOM.enable')
self._tab_obj.call_method('Page.enable')
self._tab_obj.Page.frameStoppedLoading = self._onFrameStoppedLoading
self._tab_obj.Page.frameStartedLoading = self._onFrameStartedLoading
self._tab_obj.DOM.documentUpdated = self._onDocumentUpdated
self._tab_obj.Page.loadEventFired = self._onLoadEventFired
self._tab_obj.Page.frameNavigated = self._onFrameNavigated
self._tab_obj.set_listener('Page.frameStoppedLoading', self._onFrameStoppedLoading)
self._tab_obj.set_listener('Page.frameStartedLoading', self._onFrameStartedLoading)
self._tab_obj.set_listener('DOM.documentUpdated', self._onDocumentUpdated)
self._tab_obj.set_listener('Page.loadEventFired', self._onLoadEventFired)
self._tab_obj.set_listener('Page.frameNavigated', self._onFrameNavigated)
def _get_document(self):
"""刷新cdp使用的document数据"""
@ -238,7 +238,7 @@ class ChromiumBase(BasePage):
files = self._upload_list if kwargs['mode'] == 'selectMultiple' else self._upload_list[:1]
self.run_cdp('DOM.setFileInputFiles', files=files, backendNodeId=kwargs['backendNodeId'])
self.driver.Page.fileChooserOpened = None
self.driver.set_listener('Page.fileChooserOpened', None)
self.run_cdp('Page.setInterceptFileChooserDialog', enabled=False)
self._upload_list = None
@ -972,7 +972,7 @@ class Screencast(object):
raise ValueError('save_path必须设置。')
clean_folder(self._path)
if self._mode.startswith('frugal'):
self._page.driver.Page.screencastFrame = self._onScreencastFrame
self._page.driver.set_listener('Page.screencastFrame', self._onScreencastFrame)
self._page.run_cdp('Page.startScreencast', everyNthFrame=1, quality=100)
elif not self._mode.startswith('js'):
@ -1029,7 +1029,7 @@ class Screencast(object):
return path
if self._mode.startswith('frugal'):
self._page.driver.Page.screencastFrame = None
self._page.driver.set_listener('Page.screencastFrame', None)
self._page.run_cdp('Page.stopScreencast')
else:
self._enable = False

View File

@ -3,7 +3,6 @@
@Author : g1879
@Contact : g1879@qq.com
"""
from functools import partial
from json import dumps, loads
from queue import Queue, Empty
from threading import Thread, Event
@ -11,26 +10,6 @@ from threading import Thread, Event
from websocket import WebSocketTimeoutException, WebSocketException, WebSocketConnectionClosedException, \
create_connection
from .errors import CDPError
class GenericAttr(object):
def __init__(self, name, tab):
self.__dict__['name'] = name
self.__dict__['tab'] = tab
def __getattr__(self, item):
method_name = f"{self.name}.{item}"
event_listener = self.tab.get_listener(method_name)
if event_listener:
return event_listener
return partial(self.tab.call_method, method_name)
def __setattr__(self, key, value):
self.tab.set_listener(f"{self.name}.{key}", value)
class ChromiumDriver(object):
_INITIAL_ = 'initial'
@ -167,12 +146,7 @@ class ChromiumDriver(object):
self.event_queue.task_done()
def __getattr__(self, item):
attr = GenericAttr(item, self)
setattr(self, item, attr)
return attr
def call_method(self, _method, *args, **kwargs):
def call_method(self, _method, **kwargs):
"""执行cdp方法
:param _method: cdp方法名
:param args: cdp参数
@ -182,8 +156,6 @@ class ChromiumDriver(object):
if not self._started:
self.start()
# raise RuntimeError("不能在启动前调用方法。")
if args:
raise CDPError("参数必须是key=value形式。")
if self._stopped.is_set():
return {'error': 'tab closed', 'type': 'tab_closed'}

View File

@ -47,7 +47,7 @@ class ChromiumDriver(object):
def __getattr__(self, item: str) -> Callable: ...
def call_method(self, _method: str, *args, **kwargs) -> dict: ...
def call_method(self, _method: str, **kwargs) -> dict: ...
def start(self) -> bool: ...

View File

@ -95,8 +95,8 @@ class ChromiumPage(ChromiumBase):
self._browser_driver.start()
self._alert = Alert()
self._tab_obj.Page.javascriptDialogOpening = self._on_alert_open
self._tab_obj.Page.javascriptDialogClosed = self._on_alert_close
self._tab_obj.set_listener('Page.javascriptDialogOpening', self._on_alert_open)
self._tab_obj.set_listener('Page.javascriptDialogClosed', self._on_alert_close)
self._rect = None
self._main_tab = self.tab_id
@ -106,7 +106,7 @@ class ChromiumPage(ChromiumBase):
# pass
self._process_id = None
r = self.browser_driver.SystemInfo.getProcessInfo()
r = self.browser_driver.call_method('SystemInfo.getProcessInfo')
if 'processInfo' not in r:
return None
for i in r['processInfo']:
@ -329,14 +329,14 @@ class ChromiumPage(ChromiumBase):
res_text = self._alert.text
if self._alert.type == 'prompt':
self.driver.Page.handleJavaScriptDialog(accept=accept, promptText=send)
self.driver.call_method('Page.handleJavaScriptDialog', accept=accept, promptText=send)
else:
self.driver.Page.handleJavaScriptDialog(accept=accept)
self.driver.call_method('Page.handleJavaScriptDialog', accept=accept)
return res_text
def quit(self):
"""关闭浏览器"""
self._tab_obj.Browser.close()
self._tab_obj.call_method('Browser.close')
self._tab_obj.stop()
ip, port = self.address.split(':')
while port_is_using(ip, port):
@ -431,7 +431,7 @@ class ChromiumTabRect(object):
def _get_browser_rect(self):
"""获取浏览器范围信息"""
return self._page.browser_driver.Browser.getWindowForTarget(targetId=self._page.tab_id)['bounds']
return self._page.browser_driver.call_method('Browser.getWindowForTarget', targetId=self._page.tab_id)['bounds']
# class BaseDownloadSetter(DownloadSetter):

View File

@ -101,7 +101,7 @@ class ChromiumBaseSetter(object):
:return: None
"""
if not self._page._upload_list:
self._page.driver.Page.fileChooserOpened = self._page._onFileChooserOpened
self._page.driver.set_listener('Page.fileChooserOpened', self._page._onFileChooserOpened)
self._page.run_cdp('Page.setInterceptFileChooserDialog', enabled=True)
if isinstance(files, str):

View File

@ -382,7 +382,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
if self._has_driver:
self.change_mode('s')
try:
self.driver.Browser.close()
self.driver.call_method('Browser.close')
except Exception:
pass
self._tab_obj.stop()
@ -421,7 +421,7 @@ class WebPage(SessionPage, ChromiumPage, BasePage):
self._response = None
self._has_session = None
if self._has_driver:
self._tab_obj.Browser.close()
self._tab_obj.call_method('Browser.close')
self._tab_obj.stop()
self._tab_obj = None
self._has_driver = None

View File

@ -45,7 +45,7 @@ python 版本3.6 及以上
用 requests 做数据采集面对要登录的网站时要分析数据包、JS 源码构造复杂的请求往往还要应付验证码、JS 混淆、签名参数等反爬手段,门槛较高,开发效率不高。
使用浏览器,可以很大程度上绕过这些坑,但浏览器运行效率不高。
因此,这个库设计初衷,是将它们合而为一,同时实现“写得快”和“跑得快”。能够在不同要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率。
因此,这个库设计初衷,是将它们合而为一,同时实现“写得快”和“跑得快”。能够在不同要时切换相应模式,并提供一种人性化的使用方法,提高开发和运行效率。
除了合并两者,本库还以网页为单位封装了常用功能,提供非常简便的操作和语句,使用户可减少考虑细节,专注功能实现。 以简单的方式实现强大的功能,使代码更优雅。
以前的版本是对 selenium 进行重新封装实现的。从 3.0 开始,作者另起炉灶,对底层进行了重新开发,摆脱对 selenium 的依赖,增强了功能,提升了运行效率。