Skip to content

Commit 8f3f58c

Browse files
committed
Update CDP Mode
1 parent eed4563 commit 8f3f58c

7 files changed

Lines changed: 72 additions & 29 deletions

File tree

help_docs/cdp_mode_methods.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ await tab.close()
305305
await tab.scroll_down(amount=25)
306306
await tab.scroll_up(amount=25)
307307
await tab.wait_for(selector="", text="", timeout=10)
308+
await tab.set_attributes(selector, attribute, value)
309+
await tab.internalize_links()
308310
await tab.download_file(url, filename=None)
309311
await tab.save_screenshot(
310312
filename="auto", format="png", full_page=False)

seleniumbase/core/browser_launcher.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,7 +2738,6 @@ def _set_chrome_options(
27382738
chrome_options.add_argument("--disable-save-password-bubble")
27392739
chrome_options.add_argument("--disable-single-click-autofill")
27402740
chrome_options.add_argument("--allow-file-access-from-files")
2741-
chrome_options.add_argument("--disable-component-update")
27422741
chrome_options.add_argument("--disable-prompt-on-repost")
27432742
chrome_options.add_argument("--dns-prefetch-disable")
27442743
chrome_options.add_argument("--disable-translate")
@@ -4793,7 +4792,6 @@ def get_local_driver(
47934792
if devtools and not headless:
47944793
edge_options.add_argument("--auto-open-devtools-for-tabs")
47954794
edge_options.add_argument("--allow-file-access-from-files")
4796-
edge_options.add_argument("--disable-component-update")
47974795
edge_options.add_argument("--allow-insecure-localhost")
47984796
edge_options.add_argument("--allow-running-insecure-content")
47994797
if user_agent:

seleniumbase/core/sb_cdp.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,13 +1664,15 @@ def set_attributes(self, selector, attribute, value):
16641664
css_selector = self.__convert_to_css_if_xpath(selector)
16651665
css_selector = re.escape(css_selector) # Add "\\" to special chars
16661666
css_selector = js_utils.escape_quotes_if_needed(css_selector)
1667-
js_code = """var $elements = document.querySelectorAll('%s');
1668-
var index = 0, length = $elements.length;
1669-
for(; index < length; index++){
1670-
$elements[index].setAttribute('%s','%s');}""" % (
1671-
css_selector,
1672-
attribute,
1673-
value,
1667+
js_code = (
1668+
"""var $elements = document.querySelectorAll('%s');
1669+
var index = 0, length = $elements.length;
1670+
for(; index < length; index++){
1671+
$elements[index].setAttribute('%s','%s');}""" % (
1672+
css_selector,
1673+
attribute,
1674+
value,
1675+
)
16741676
)
16751677
with suppress(Exception):
16761678
self.loop.run_until_complete(self.page.evaluate(js_code))
@@ -1965,8 +1967,8 @@ def _on_a_cf_turnstile_page(self, source=None):
19651967
return True
19661968
return False
19671969

1968-
def _on_a_g_recaptcha_page(self, source=None):
1969-
time.sleep(0.4)
1970+
def _on_a_g_recaptcha_page(self, *args, **kwargs):
1971+
time.sleep(0.4) # reCAPTCHA may need a moment to appear
19701972
self.loop.run_until_complete(self.page.wait())
19711973
source = self.get_page_source()
19721974
if (

seleniumbase/undetected/cdp_driver/browser.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ async def start(self=None) -> Browser:
580580
) # noqa
581581
exe = self.config.browser_executable_path
582582
params = self.config()
583-
logger.info(
583+
logger.debug(
584584
"Starting\n\texecutable :%s\n\narguments:\n%s",
585585
exe,
586586
"\n\t".join(params),
@@ -636,7 +636,7 @@ async def start(self=None) -> Browser:
636636
self.info.webSocketDebuggerUrl, browser=self
637637
)
638638
if self.config.autodiscover_targets:
639-
logger.info("Enabling autodiscover targets")
639+
logger.debug("Enabling autodiscover targets")
640640
self.connection.handlers[cdp.target.TargetInfoChanged] = [
641641
self._handle_target_update
642642
]
@@ -863,15 +863,15 @@ def stop(self):
863863
for _ in range(3):
864864
try:
865865
self._process.terminate()
866-
logger.info(
866+
logger.debug(
867867
"Terminated browser with pid %d successfully."
868868
% self._process.pid
869869
)
870870
break
871871
except (Exception,):
872872
try:
873873
self._process.kill()
874-
logger.info(
874+
logger.debug(
875875
"Killed browser with pid %d successfully."
876876
% self._process.pid
877877
)
@@ -880,14 +880,14 @@ def stop(self):
880880
try:
881881
if hasattr(self, "browser_process_pid"):
882882
os.kill(self._process_pid, 15)
883-
logger.info(
883+
logger.debug(
884884
"Killed browser with pid %d "
885885
"using signal 15 successfully."
886886
% self._process.pid
887887
)
888888
break
889889
except (TypeError,):
890-
logger.info("typerror", exc_info=True)
890+
logger.info("TypeError", exc_info=True)
891891
pass
892892
except (PermissionError,):
893893
logger.info(
@@ -896,7 +896,7 @@ def stop(self):
896896
)
897897
pass
898898
except (ProcessLookupError,):
899-
logger.info("Process lookup failure!")
899+
logger.info("ProcessLookupError")
900900
pass
901901
except (Exception,):
902902
raise

seleniumbase/undetected/cdp_driver/config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ def __init__(
207207
"--disable-top-sites",
208208
"--disable-translate",
209209
"--dns-prefetch-disable",
210-
"--disable-component-update",
211210
"--disable-renderer-backgrounding",
212211
"--disable-dev-shm-usage",
213212
]

seleniumbase/undetected/cdp_driver/element.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,10 @@ async def click_async(self):
372372
arguments = [cdp.runtime.CallArgument(
373373
object_id=self._remote_object.object_id
374374
)]
375-
await self.flash_async(0.25)
375+
script = 'sessionStorage.getItem("pxsid") !== null;'
376+
using_px = await self.tab.evaluate(script)
377+
if not using_px:
378+
await self.flash_async(0.25)
376379
await self._tab.send(
377380
cdp.runtime.call_function_on(
378381
"(el) => el.click()",
@@ -501,7 +504,10 @@ async def mouse_click_async(
501504
logger.warning("Could not calculate box model for %s", self)
502505
return
503506
logger.debug("Clicking on location: %.2f, %.2f" % center)
504-
asyncio.create_task(self.flash_async(0.25))
507+
script = 'sessionStorage.getItem("pxsid") !== null;'
508+
using_px = await self.tab.evaluate(script)
509+
if not using_px:
510+
asyncio.create_task(self.flash_async(0.25))
505511
asyncio.create_task(
506512
self._tab.send(
507513
cdp.input_.dispatch_mouse_event(
@@ -560,12 +566,15 @@ async def mouse_click_with_offset_async(
560566
logger.debug("Clicking on location: %.2f, %.2f" % center_pos)
561567
else:
562568
logger.debug("Clicking on location: %.2f, %.2f" % (x_pos, y_pos))
563-
asyncio.create_task(
564-
self.flash_async(
565-
x_offset=x_offset - (width / 2),
566-
y_offset=y_offset - (height / 2),
567-
),
568-
)
569+
script = 'sessionStorage.getItem("pxsid") !== null;'
570+
using_px = await self.tab.evaluate(script)
571+
if not using_px:
572+
asyncio.create_task(
573+
self.flash_async(
574+
x_offset=x_offset - (width / 2),
575+
y_offset=y_offset - (height / 2),
576+
),
577+
)
569578
asyncio.create_task(
570579
self._tab.send(
571580
cdp.input_.dispatch_mouse_event(

seleniumbase/undetected/cdp_driver/tab.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,39 @@ async def wait_for(
10921092
await self.sleep(0.068)
10931093
return item
10941094

1095+
async def set_attributes(self, selector, attribute, value):
1096+
"""This method uses JavaScript to set/update a common attribute.
1097+
All matching selectors from querySelectorAll() are used.
1098+
Example => (Make all links on a website redirect to Google):
1099+
self.set_attributes("a", "href", "https://google.com")"""
1100+
attribute = re.escape(attribute)
1101+
attribute = js_utils.escape_quotes_if_needed(attribute)
1102+
value = re.escape(value)
1103+
value = js_utils.escape_quotes_if_needed(value)
1104+
if selector.startswith(("/", "./", "(")):
1105+
with suppress(Exception):
1106+
selector = js_utils.convert_to_css_selector(selector, "xpath")
1107+
css_selector = selector
1108+
css_selector = re.escape(css_selector) # Add "\\" to special chars
1109+
css_selector = js_utils.escape_quotes_if_needed(css_selector)
1110+
js_code = (
1111+
"""var $elements = document.querySelectorAll('%s');
1112+
var index = 0, length = $elements.length;
1113+
for(; index < length; index++){
1114+
$elements[index].setAttribute('%s','%s');}""" % (
1115+
css_selector,
1116+
attribute,
1117+
value,
1118+
)
1119+
)
1120+
with suppress(Exception):
1121+
await self.evaluate(js_code)
1122+
1123+
async def internalize_links(self):
1124+
"""All `target="_blank"` links become `target="_self"`.
1125+
This prevents those links from opening in a new tab."""
1126+
await self.set_attributes('[target="_blank"]', "target", "_self")
1127+
10951128
async def download_file(
10961129
self, url: str, filename: Optional[PathLike] = None
10971130
):
@@ -1336,8 +1369,8 @@ async def __on_a_cf_turnstile_page(self, source=None):
13361369
return True
13371370
return False
13381371

1339-
async def __on_a_g_recaptcha_page(self, source=None):
1340-
await self.sleep(0.4)
1372+
async def __on_a_g_recaptcha_page(self, *args, **kwargs):
1373+
await self.sleep(0.4) # reCAPTCHA may need a moment to appear
13411374
source = await self.get_html()
13421375
if (
13431376
(

0 commit comments

Comments
 (0)