Update CDP Mode

This commit is contained in:
Michael Mintz 2025-03-22 15:07:59 -04:00
parent 0b9852f804
commit 9bde7e7387
5 changed files with 60 additions and 7 deletions

View File

@ -512,6 +512,7 @@ sb.cdp.scroll_to_bottom()
sb.cdp.scroll_up(amount=25) sb.cdp.scroll_up(amount=25)
sb.cdp.scroll_down(amount=25) sb.cdp.scroll_down(amount=25)
sb.cdp.save_screenshot(name, folder=None, selector=None) sb.cdp.save_screenshot(name, folder=None, selector=None)
sb.cdp.print_to_pdf(name, folder=None)
``` ```
-------- --------

View File

@ -1,4 +1,5 @@
import fasteners import fasteners
import json
import logging import logging
import os import os
import platform import platform
@ -769,6 +770,7 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.scroll_up = CDPM.scroll_up cdp.scroll_up = CDPM.scroll_up
cdp.scroll_down = CDPM.scroll_down cdp.scroll_down = CDPM.scroll_down
cdp.save_screenshot = CDPM.save_screenshot cdp.save_screenshot = CDPM.save_screenshot
cdp.print_to_pdf = CDPM.print_to_pdf
cdp.page = page # async world cdp.page = page # async world
cdp.driver = driver.cdp_base # async world cdp.driver = driver.cdp_base # async world
cdp.tab = cdp.page # shortcut (original) cdp.tab = cdp.page # shortcut (original)
@ -2125,6 +2127,15 @@ def _set_chrome_options(
prefs["enable_do_not_track"] = True prefs["enable_do_not_track"] = True
if external_pdf: if external_pdf:
prefs["plugins.always_open_pdf_externally"] = True prefs["plugins.always_open_pdf_externally"] = True
pdf_settings = {
"recentDestinations": [
{"id": "Save as PDF", "origin": "local", "account": ""}
],
"selectedDestinationId": "Save as PDF",
"version": 2,
}
app_state = "printing.print_preview_sticky_settings.appState"
prefs[app_state] = json.dumps(pdf_settings)
if proxy_string or proxy_pac_url: if proxy_string or proxy_pac_url:
# Implementation of https://stackoverflow.com/q/65705775/7058266 # Implementation of https://stackoverflow.com/q/65705775/7058266
prefs["webrtc.ip_handling_policy"] = "disable_non_proxied_udp" prefs["webrtc.ip_handling_policy"] = "disable_non_proxied_udp"
@ -3299,7 +3310,6 @@ def get_remote_driver(
from seleniumbase.core import capabilities_parser from seleniumbase.core import capabilities_parser
desired_caps = capabilities_parser.get_desired_capabilities(cap_file) desired_caps = capabilities_parser.get_desired_capabilities(cap_file)
if cap_string: if cap_string:
import json
try: try:
extra_caps = json.loads(str(cap_string)) extra_caps = json.loads(str(cap_string))
except Exception as e: except Exception as e:

View File

@ -2181,6 +2181,12 @@ class CDPMethods():
else: else:
self.select(selector).save_screenshot(filename) self.select(selector).save_screenshot(filename)
def print_to_pdf(self, name, folder=None):
filename = name
if folder:
filename = os.path.join(folder, name)
self.loop.run_until_complete(self.page.print_to_pdf(filename))
class Chrome(CDPMethods): class Chrome(CDPMethods):
def __init__(self, url=None, **kwargs): def __init__(self, url=None, **kwargs):

View File

@ -459,7 +459,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if self.current_url.startswith( if self.current_url.startswith(
"chrome-extension://" "chrome-extension://"
): ):
self.close() # https://issues.chromium.org/issues/396611138
# (Uncomment below when resolved)
# self.close()
if self.service.is_connectable(): if self.service.is_connectable():
self.stop_client() self.stop_client()
self.service.stop() self.service.stop()
@ -496,7 +498,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if self.current_url.startswith( if self.current_url.startswith(
"chrome-extension://" "chrome-extension://"
): ):
self.close() # https://issues.chromium.org/issues/396611138
# (Uncomment below when resolved)
# self.close()
if self.service.is_connectable(): if self.service.is_connectable():
self.stop_client() self.stop_client()
self.service.stop() self.service.stop()

View File

@ -1,7 +1,10 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
import base64
import datetime
import logging import logging
import pathlib import pathlib
import urllib.parse
import warnings import warnings
from typing import Dict, List, Union, Optional, Tuple from typing import Dict, List, Union, Optional, Tuple
from . import browser as cdp_browser from . import browser as cdp_browser
@ -1133,9 +1136,6 @@ class Tab(Connection):
:return: The path/filename of the saved screenshot. :return: The path/filename of the saved screenshot.
:rtype: str :rtype: str
""" """
import urllib.parse
import datetime
await self.sleep() # Update the target's URL await self.sleep() # Update the target's URL
path = None path = None
if format.lower() in ["jpg", "jpeg"]: if format.lower() in ["jpg", "jpeg"]:
@ -1166,8 +1166,40 @@ class Tab(Connection):
"Most possible cause is the page " "Most possible cause is the page "
"has not finished loading yet." "has not finished loading yet."
) )
import base64 data_bytes = base64.b64decode(data)
if not path:
raise RuntimeError("Invalid filename or path: '%s'" % filename)
path.write_bytes(data_bytes)
return str(path)
async def print_to_pdf(
self,
filename: Optional[PathLike] = "auto",
) -> str:
"""
Saves a webpage as a PDF.
:param filename: uses this as the save path
:type filename: PathLike
:return: The path/filename of the saved screenshot.
:rtype: str
"""
await self.sleep() # Update the target's URL
path = None
ext = ".pdf"
if not filename or filename == "auto":
parsed = urllib.parse.urlparse(self.target.url)
parts = parsed.path.split("/")
last_part = parts[-1]
last_part = last_part.rsplit("?", 1)[0]
dt_str = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
candidate = f"{parsed.hostname}__{last_part}_{dt_str}"
path = pathlib.Path(candidate + ext) # noqa
else:
path = pathlib.Path(filename)
path.parent.mkdir(parents=True, exist_ok=True)
data, _ = await self.send(cdp.page.print_to_pdf())
if not data:
raise ProtocolException("Could not save PDF.")
data_bytes = base64.b64decode(data) data_bytes = base64.b64decode(data)
if not path: if not path:
raise RuntimeError("Invalid filename or path: '%s'" % filename) raise RuntimeError("Invalid filename or path: '%s'" % filename)