get_src()增加支持blob

This commit is contained in:
g1879 2023-10-22 10:00:53 +08:00
parent f79a91b5a1
commit e5a2a25473
7 changed files with 68 additions and 38 deletions

View File

@ -137,12 +137,9 @@ class ChromiumDriver(object):
except Empty: except Empty:
continue continue
if event['method'] in self.event_handlers: function = self.event_handlers.get(event['method'])
try: if function:
self.event_handlers[event['method']](**event['params']) function(**event['params'])
except Exception as e:
raise
# raise RuntimeError(f"\n回调函数错误\n{e}")
self.event_queue.task_done() self.event_queue.task_done()

View File

@ -5,7 +5,9 @@
""" """
from queue import Queue from queue import Queue
from threading import Thread, Event from threading import Thread, Event
from typing import Union, Callable, Dict from typing import Union, Callable, Dict, Optional
from websocket import WebSocket
class GenericAttr(object): class GenericAttr(object):
@ -24,7 +26,7 @@ class ChromiumDriver(object):
has_alert: bool has_alert: bool
_websocket_url: str _websocket_url: str
_cur_id: int _cur_id: int
_ws = None _ws: Optional[WebSocket]
_recv_th: Thread _recv_th: Thread
_handle_event_th: Thread _handle_event_th: Thread
_stopped: Event _stopped: Event

View File

@ -117,8 +117,7 @@ class ChromiumOptions(object):
@debugger_address.setter @debugger_address.setter
def debugger_address(self, address): def debugger_address(self, address):
"""设置浏览器地址格式ip:port""" """设置浏览器地址格式ip:port"""
address = address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://') self.set_debugger_address(address)
self._debugger_address = address
@property @property
def arguments(self): def arguments(self):
@ -349,7 +348,8 @@ class ChromiumOptions(object):
:param address: 浏览器地址 :param address: 浏览器地址
:return: 当前对象 :return: 当前对象
""" """
self.debugger_address = address address = address.replace('localhost', '127.0.0.1').lstrip('http://').lstrip('https://')
self._debugger_address = address
return self return self
def set_browser_path(self, path): def set_browser_path(self, path):

View File

@ -454,31 +454,64 @@ class ChromiumElement(DrissionElement):
while not self.run_js(js) and perf_counter() < end_time: while not self.run_js(js) and perf_counter() < end_time:
sleep(.1) sleep(.1)
src = self.attr('src')
is_blob = src.startswith('blob')
result = None result = None
end_time = perf_counter() + timeout end_time = perf_counter() + timeout
while perf_counter() < end_time: while perf_counter() < end_time:
src = self.prop('currentSrc') if is_blob:
if not src: js = """
continue function fetchData(url) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {resolve(reader.result);}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url, true);
xhr.send();
});
}
"""
try:
result = self.page.run_js(js, src)
break
except:
continue
node = self.page.run_cdp('DOM.describeNode', backendNodeId=self._backend_id)['node'] else:
frame = node.get('frameId', None) src = self.prop('currentSrc')
frame = frame or self.page._target_id if not src:
continue
try: node = self.page.run_cdp('DOM.describeNode', backendNodeId=self._backend_id)['node']
result = self.page.run_cdp('Page.getResourceContent', frameId=frame, url=src) frame = node.get('frameId', None)
break frame = frame or self.page._target_id
except CDPError:
sleep(.1) try:
result = self.page.run_cdp('Page.getResourceContent', frameId=frame, url=src)
break
except CDPError:
sleep(.1)
if not result: if not result:
return None return None
if result['base64Encoded'] and base64_to_bytes: if is_blob:
from base64 import b64decode if base64_to_bytes:
return b64decode(result['content']) from base64 import b64decode
return b64decode(result.split(',', 1)[1])
else:
return result
else: else:
return result['content'] if result['base64Encoded'] and base64_to_bytes:
from base64 import b64decode
return b64decode(result['content'])
else:
return result['content']
def save(self, path=None, name=None, timeout=None): def save(self, path=None, name=None, timeout=None):
"""保存图片或其它有src属性的元素的资源 """保存图片或其它有src属性的元素的资源

View File

@ -49,11 +49,11 @@ class ChromiumPage(ChromiumBase):
# 接收浏览器地址和端口 # 接收浏览器地址和端口
elif isinstance(addr_driver_opts, str): elif isinstance(addr_driver_opts, str):
self._driver_options = ChromiumOptions() self._driver_options = ChromiumOptions()
self._driver_options.debugger_address = addr_driver_opts self._driver_options.set_debugger_address(addr_driver_opts)
elif isinstance(addr_driver_opts, ChromiumDriver): elif isinstance(addr_driver_opts, ChromiumDriver):
self._driver_options = ChromiumOptions(False) self._driver_options = ChromiumOptions(False)
self._driver_options.debugger_address = addr_driver_opts.address self._driver_options.set_debugger_address(addr_driver_opts.address)
self._driver = addr_driver_opts self._driver = addr_driver_opts
else: else:

View File

@ -24,7 +24,6 @@ class BrowserDownloadManager(object):
t = TabDownloadSettings(self._page.tab_id) t = TabDownloadSettings(self._page.tab_id)
t.path = self._page.download_path t.path = self._page.download_path
self._missions = {} # {guid: DownloadMission} self._missions = {} # {guid: DownloadMission}
self._tabs_settings = {self._page.tab_id: t} # {tab_id: TabDownloadSettings}
self._tab_missions = {} # {tab_id: DownloadMission} self._tab_missions = {} # {tab_id: DownloadMission}
self._flags = {} # {tab_id: [bool, DownloadMission]} self._flags = {} # {tab_id: [bool, DownloadMission]}
@ -44,7 +43,7 @@ class BrowserDownloadManager(object):
:param path: 下载路径 :param path: 下载路径
:return: None :return: None
""" """
self._tabs_settings.setdefault(tab_id, TabDownloadSettings(tab_id)).path = str(Path(path).absolute()) TabDownloadSettings(tab_id).path = str(Path(path).absolute())
if tab_id == self._page.tab_id: if tab_id == self._page.tab_id:
self._browser.run_cdp('Browser.setDownloadBehavior', downloadPath=str(Path(path).absolute()), self._browser.run_cdp('Browser.setDownloadBehavior', downloadPath=str(Path(path).absolute()),
behavior='allowAndName', eventsEnabled=True) behavior='allowAndName', eventsEnabled=True)
@ -55,7 +54,7 @@ class BrowserDownloadManager(object):
:param rename: 文件名 :param rename: 文件名
:return: None :return: None
""" """
self._tabs_settings.setdefault(tab_id, TabDownloadSettings(tab_id)).rename = rename TabDownloadSettings(tab_id).rename = rename
def set_file_exists(self, tab_id, mode): def set_file_exists(self, tab_id, mode):
"""设置某个tab下载文件重名时执行的策略 """设置某个tab下载文件重名时执行的策略
@ -63,7 +62,7 @@ class BrowserDownloadManager(object):
:param mode: 下载路径 :param mode: 下载路径
:return: None :return: None
""" """
self._tabs_settings.setdefault(tab_id, TabDownloadSettings(tab_id)).when_file_exists = mode TabDownloadSettings(tab_id).when_file_exists = mode
def set_flag(self, tab_id, flag): def set_flag(self, tab_id, flag):
"""设置某个tab的重命名文件名 """设置某个tab的重命名文件名
@ -125,7 +124,6 @@ class BrowserDownloadManager(object):
:param tab_id: 标签页id :param tab_id: 标签页id
:return: None :return: None
""" """
self._tabs_settings.pop(tab_id)
self._tab_missions.pop(tab_id) self._tab_missions.pop(tab_id)
self._flags.pop(tab_id) self._flags.pop(tab_id)
TabDownloadSettings.TABS.pop(tab_id) TabDownloadSettings.TABS.pop(tab_id)
@ -135,7 +133,7 @@ class BrowserDownloadManager(object):
guid = kwargs['guid'] guid = kwargs['guid']
tab_id = self._browser._frames.get(kwargs['frameId'], self._page.tab_id) tab_id = self._browser._frames.get(kwargs['frameId'], self._page.tab_id)
settings = TabDownloadSettings(tab_id) settings = TabDownloadSettings(tab_id if tab_id in TabDownloadSettings.TABS else self._page.tab_id)
if settings.rename: if settings.rename:
tmp = kwargs['suggestedFilename'].rsplit('.', 1) tmp = kwargs['suggestedFilename'].rsplit('.', 1)
ext_name = tmp[-1] if len(tmp) > 1 else '' ext_name = tmp[-1] if len(tmp) > 1 else ''
@ -165,7 +163,8 @@ class BrowserDownloadManager(object):
else: else:
self._tab_missions.setdefault(tab_id, []).append(guid) self._tab_missions.setdefault(tab_id, []).append(guid)
self._flags[tab_id] = m if self.get_flag(tab_id) is not None:
self._flags[tab_id] = m
def _onDownloadProgress(self, **kwargs): def _onDownloadProgress(self, **kwargs):
"""下载状态变化时执行""" """下载状态变化时执行"""

View File

@ -1,5 +1,5 @@
from pathlib import Path from pathlib import Path
from typing import Dict, Optional, Union from typing import Dict, Optional, Union, Literal
from .._base.browser import Browser from .._base.browser import Browser
from .._pages.chromium_page import ChromiumPage from .._pages.chromium_page import ChromiumPage
@ -10,7 +10,6 @@ class BrowserDownloadManager(object):
_page: ChromiumPage = ... _page: ChromiumPage = ...
_missions: Dict[str, DownloadMission] = ... _missions: Dict[str, DownloadMission] = ...
_tab_missions: dict = ... _tab_missions: dict = ...
_tabs_settings: Dict[str, TabDownloadSettings] = ...
_flags: dict = ... _flags: dict = ...
def __init__(self, browser: Browser): ... def __init__(self, browser: Browser): ...
@ -22,7 +21,7 @@ class BrowserDownloadManager(object):
def set_rename(self, tab_id: str, rename: str) -> None: ... def set_rename(self, tab_id: str, rename: str) -> None: ...
def set_file_exists(self, tab_id: str, mode: str) -> None: ... def set_file_exists(self, tab_id: str, mode: Literal['rename', 'skip', 'overwrite']) -> None: ...
def set_flag(self, tab_id: str, flag: Optional[bool, DownloadMission]) -> None: ... def set_flag(self, tab_id: str, flag: Optional[bool, DownloadMission]) -> None: ...