Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/cdp_mode/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,13 @@ with SB(uc=True, test=True, ad_block=True) as sb:
items = sb.find_elements('[data-item-id]')
for item in items:
if required_text.lower() in item.text.lower():
description = item.querySelector(
description = item.query_selector(
'[data-automation-id="product-title"]'
)
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
print("* " + description.text)
price = item.querySelector(
price = item.query_selector(
'[data-automation-id="product-price"]'
)
if price:
Expand Down
4 changes: 2 additions & 2 deletions examples/cdp_mode/playwright/raw_nordstrom_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
unique_item_text = []
items = sb.find_elements("article")
for item in items:
description = item.querySelector("article h3")
description = item.query_selector("article h3")
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
price_text = ""
price = item.querySelector('div div span[aria-hidden="true"]')
price = item.query_selector('div div span[aria-hidden="true"]')
if price:
price_text = price.text
print("* %s (%s)" % (description.text, price_text))
Expand Down
25 changes: 25 additions & 0 deletions examples/cdp_mode/raw_cdp_immoscout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""An example that bypasses the DataDome Slider CAPTCHA.
(PyAutoGUI is installed at runtime if not yet installed.)"""
from seleniumbase import sb_cdp

sb = sb_cdp.Chrome(use_chromium=True, locale="en")
sb.goto("https://www.immoscout24.ch/en/real-estate/rent")
sb.sleep(1.6)
sb.solve_captcha()
sb.sleep(2.5)
sb.click_if_visible("#onetrust-accept-btn-handler", timeout=3)
sb.sleep(0.5)
sb.click('[data-cy="Locations_searchFieldOpener"]')
sb.sleep(0.6)
sb.press_keys('[data-cy="Locations_searchField"]', "Bern")
sb.sleep(0.6)
sb.click_if_visible('b:contains("Bern")', timeout=2)
sb.sleep(2.1)
sb.click('button[data-cy="SearchBar_button"]')
sb.sleep(3.5)
print("*** " + sb.get_text("h1"))
items = sb.find_elements('[data-test="result-list-item"]')
for item in items:
item.flash(color="44CC88")
print(item.query_selector('[class*="mainTitle"]').text)
print(item.query_selector("address").text)
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_cdp_nordstrom.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
unique_item_text = []
items = sb.find_elements("article")
for item in items:
description = item.querySelector("article h3")
description = item.query_selector("article h3")
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
price_text = ""
price = item.querySelector('div div span[aria-hidden="true"]')
price = item.query_selector('div div span[aria-hidden="true"]')
if price:
price_text = price.text
print("* %s (%s)" % (description.text, price_text))
Expand Down
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_cdp_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
items = sb.find_elements('[data-test="product-details"]')
for item in items:
if required_text.lower() in item.text.lower():
description = item.querySelector('a[data-test*="Card/title"]')
description = item.query_selector('a[data-test*="Card/title"]')
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
print("* " + description.text)
price = item.querySelector('[data-test="current-price"]')
price = item.query_selector('[data-test="current-price"]')
if price:
print(" (" + price.text + ")")
item.scroll_into_view()
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_cdp_walmart.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
items = sb.find_elements('[data-item-id]')
for item in items:
if required_text.lower() in item.text.lower():
description = item.querySelector(
description = item.query_selector(
'[data-automation-id="product-title"]'
)
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
print("* " + description.text)
price = item.querySelector(
price = item.query_selector(
'[data-automation-id="product-price"]'
)
if price:
Expand Down
5 changes: 3 additions & 2 deletions examples/cdp_mode/raw_chatgpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
sb.activate_cdp_mode()
sb.open("https://chatgpt.com/")
sb.sleep(1)
sb.click_if_visible('button[aria-label="Close dialog"]')
sb.click_if_visible('button[data-testid="close-button"]')
close_1 = 'button[aria-label="Close dialog"]'
close_2 = 'button[data-testid="close-button"]'
sb.click_if_visible("%s, %s" % (close_1, close_2))
query = "Compare Playwright to SeleniumBase in under 178 words"
sb.press_keys("#prompt-textarea", query)
sb.click('button[data-testid="send-button"]')
Expand Down
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_idealista.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
items = sb.find_elements("div.item-info-container")
for item in items:
item.flash(color="44CC88")
print(item.querySelector("a.item-link").text)
print(item.querySelector("span.item-price").text)
print(item.query_selector("a.item-link").text)
print(item.query_selector("span.item-price").text)
26 changes: 0 additions & 26 deletions examples/cdp_mode/raw_immoscout.py

This file was deleted.

4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_nordstrom.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
unique_item_text = []
items = sb.find_elements("article")
for item in items:
description = item.querySelector("article h3")
description = item.query_selector("article h3")
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
price_text = ""
price = item.querySelector('div div span[aria-hidden="true"]')
price = item.query_selector('div div span[aria-hidden="true"]')
if price:
price_text = price.text
print("* %s (%s)" % (description.text, price_text))
Expand Down
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_softpedia.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
sb.wait_for_element(item_container)
items = sb.find_elements(item_container)
for item in items:
result = item.querySelector("h4 a")
result = item.query_selector("h4 a")
links.append(result.get_attribute("href"))
print("* " + result.text)
print(item.querySelector("p").get_attribute("title"))
print(item.query_selector("p").get_attribute("title"))
for link in links:
sb.goto(link)
sb.remove_elements("div.ad")
Expand Down
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
items = sb.find_elements('[data-test="product-details"]')
for item in items:
if required_text.lower() in item.text.lower():
description = item.querySelector('a[data-test*="Card/title"]')
description = item.query_selector('a[data-test*="Card/title"]')
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
print("* " + description.text)
price = item.querySelector('[data-test="current-price"]')
price = item.query_selector('[data-test="current-price"]')
if price:
print(" (" + price.text + ")")
item.scroll_into_view()
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_walmart.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
items = sb.find_elements('[data-item-id]')
for item in items:
if required_text.lower() in item.text.lower():
description = item.querySelector(
description = item.query_selector(
'[data-automation-id="product-title"]'
)
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
print("* " + description.text)
price = item.querySelector(
price = item.query_selector(
'[data-automation-id="product-price"]'
)
if price:
Expand Down
1 change: 1 addition & 0 deletions examples/cdp_mode/raw_xpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
sb.cdp.goto("https://seleniumbase.io/demo_page")
sb.cdp.highlight('//input[@id="myTextInput"]')
sb.cdp.type('//*[@id="myTextInput"]', "XPath Test!")
sb.cdp.type('//input[@name="text" or @name="preText2"]', "Xpath Here!")
sb.cdp.sleep(0.5)
sb.cdp.highlight('//button[contains(text(),"(Green)")]')
sb.cdp.click('//button[starts-with(text(),"Click Me")]')
Expand Down
8 changes: 4 additions & 4 deletions examples/presenter/uc_presentation_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ def test_presentation_4(self):
items = sb.find_elements('[data-item-id]')
for item in items:
if required_text.lower() in item.text.lower():
description = item.querySelector(
description = item.query_selector(
'[data-automation-id="product-title"]'
)
if (
Expand All @@ -540,7 +540,7 @@ def test_presentation_4(self):
):
unique_item_text.append(description.text)
print("* " + description.text)
price = item.querySelector(
price = item.query_selector(
'[data-automation-id="product-price"]'
)
if price:
Expand Down Expand Up @@ -879,11 +879,11 @@ def test_presentation_4(self):
unique_item_text = []
items = sb.find_elements("article")
for item in items:
description = item.querySelector("article h3")
description = item.query_selector("article h3")
if description and description.text not in unique_item_text:
unique_item_text.append(description.text)
price_text = ""
price = item.querySelector(
price = item.query_selector(
'div div span[aria-hidden="true"]'
)
if price:
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "4.51.0"
__version__ = "4.51.1"
8 changes: 3 additions & 5 deletions seleniumbase/config/proxy_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@
If you don't already have a proxy server to connect to,
you can try finding one from one of following sites:
* https://www.sslproxies.org/
* https://bit.ly/36GtZa1
* https://www.us-proxy.org/
* https://hidemy.name/en/proxy-list/
* http://free-proxy.cz/en/proxylist/country/all/https/ping/all
"""

PROXY_LIST = {
"example1": "98.8.195.160:443", # (Example) - set your own proxy here
"example2": "200.174.198.86:8888", # (Example)
"example3": "socks5://184.178.172.5:15303", # (Example)
"example1": "65.109.191.98:3080", # (Example) - set your own proxy here
"example2": "157.254.194.57:1080", # (Example)
"example3": "socks4://142.54.228.193:4145", # (Example)
"proxy1": None,
"proxy2": None,
"proxy3": None,
Expand Down
13 changes: 9 additions & 4 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -2219,7 +2219,8 @@ def _on_a_datadome_slider_page(self, *args, **kwargs):
self.loop.run_until_complete(self.page.wait(0.05))
if (
self.is_element_visible(
'body > iframe[src*="/geo.captcha-delivery.com/captcha/"]'
'body > iframe[src*="/geo.captcha-delivery.com/captcha/"], '
'body > iframe[src*="/geo.captcha-delivery.com/interstitial/"]'
)
):
return True
Expand Down Expand Up @@ -2305,14 +2306,18 @@ def __gui_click_recaptcha(self, use_cdp=False):
return False

def __gui_slide_datadome_captcha(self):
iframe = 'body > iframe[src*="/geo.captcha-delivery.com/captcha/"]'
iframe = (
'body > iframe[src*="/geo.captcha-delivery.com/captcha/"], '
'body > iframe[src*="/geo.captcha-delivery.com/interstitial/"]'
)
if not self.is_element_visible(iframe):
return False
src = self.get_attribute(iframe, "src")
tab = self.get_active_tab()
time.sleep(0.05)
self.open_new_tab(url=src)
time.sleep(0.41)
self.loop.run_until_complete(self.page.wait(0.1))
time.sleep(0.42)
self.loop.run_until_complete(self.page.wait(0.12))
time.sleep(0.25)
x1, y1 = self.get_gui_element_center("div.slider")
x2, y2 = self.get_gui_element_center("div.sliderTarget")
Expand Down
14 changes: 13 additions & 1 deletion seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,15 @@ def open(self, url, **kwargs):
shared_utils.check_if_time_limit_exceeded()
self._check_browser()
time.sleep(0.8)
self.driver.get(url)
try:
self.driver.get(url)
except Exception as e2:
if "ERR_CONNECTION_RESET" in e2.msg and self.proxy_string:
message = "ERR_CONNECTION_RESET: "
message += "Invalid proxy and/or Internet unreachable!"
raise ProxyConnectionException(message)
else:
raise
elif (
"ERR_INTERNET_DISCONNECTED" in e.msg
or "neterror?e=dnsNotFound" in e.msg
Expand Down Expand Up @@ -355,6 +363,10 @@ def open(self, url, **kwargs):
logging.debug("Invalid session id. Will open new browser.")
self.driver = self.get_new_driver()
self.driver.get(url)
elif "ERR_TUNNEL_CONNECTION_FAILED" in e.msg and self.proxy_string:
message = "ERR_CONNECTION_RESET: "
message += "Bad proxy and/or Internet unreachable!"
raise ProxyConnectionException(message)
else:
raise
try:
Expand Down
19 changes: 19 additions & 0 deletions seleniumbase/fixtures/xpath_to_css.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,25 @@ def convert_xpath_to_css(xpath):
s_val2 = data.group(5)
return '%s[%s="%s"][%s="%s"]' % (s_tag, s_atr1, s_val1, s_atr2, s_val2)

# Find instance of: //tag[@attribute1='value1' or @attribute2='value2']
# This tracks single/double quotes and maps them to comma-separated CSS.
data = re.match(
r"^\s*//([\w\-*]*)\s*\[\s*@?([\w\-:]+)\s*=\s*[\"']([^\"']*)[\"']\s+"
r"or\s+@?([\w\-:]+)\s*=\s*[\"']([^\"']*)[\"']\s*\]",
xpath,
)
if data:
s_tag = data.group(1)
if s_tag == "*":
s_tag = ""
s_atr1 = data.group(2)
s_val1 = data.group(3)
s_atr2 = data.group(4)
s_val2 = data.group(5)
return '%s[%s="%s"], %s[%s="%s"]' % (
s_tag, s_atr1, s_val1, s_tag, s_atr2, s_val2
)

# **** End of handling special xpath edge cases instantly ****

if xpath[0] != '"' and xpath[-1] != '"' and xpath.count('"') % 2 == 0:
Expand Down
2 changes: 2 additions & 0 deletions seleniumbase/undetected/cdp_driver/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,11 +493,13 @@ async def get(
"*.pubmatic.com*",
"*.id5-sync.com*",
"*.moatads.com*",
"*.viously.com*",
"*.dotomi.com*",
"*.adsrvr.org*",
"*.atmtd.com*",
"*.liadm.com*",
"*.loopme.me*",
"*.flashb.id*",
"*.adnxs.com*",
"*.openx.net*",
"*.tapad.com*",
Expand Down
2 changes: 2 additions & 0 deletions seleniumbase/undetected/cdp_driver/cdp_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,8 @@ async def start(
proxy_pass,
proxy_scheme,
)
elif proxy:
proxy = proxy_helper.validate_proxy_string(proxy_string)
if "binary_location" in kwargs and not browser_executable_path:
browser_executable_path = kwargs["binary_location"]
if not user_data_dir and "--user-data-dir" in arg_join:
Expand Down