Skip to content

Commit 76a1e95

Browse files
authored
Merge pull request #3743 from seleniumbase/proxy-scheme-customization
Proxy scheme customization
2 parents ae27edd + fa53648 commit 76a1e95

File tree

9 files changed

+127
-20
lines changed

9 files changed

+127
-20
lines changed

examples/cdp_mode/raw_proxy.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from seleniumbase import decorators
2+
from seleniumbase import sb_cdp
3+
4+
# Change this to "ip:port" or "user:pass@ip:port"
5+
proxy = None
6+
7+
8+
@decorators.print_runtime("CDP Proxy Example")
9+
def main():
10+
url = "https://api.ipify.org/"
11+
sb = sb_cdp.Chrome(url, lang="en", pls="none", proxy=proxy)
12+
ip_address = sb.get_text("body")
13+
if "ERR" in ip_address:
14+
raise Exception("Failed to determine IP Address!")
15+
print("\n\nMy IP Address = %s\n" % ip_address)
16+
sb.open("https://ipinfo.io/%s" % ip_address)
17+
sb.sleep(2)
18+
sb.wait_for_text(ip_address, "h1", timeout=20)
19+
sb.find_element('[href="/signup"]')
20+
sb.wait_for_text("Hosted domains", timeout=20)
21+
sb.highlight("h1")
22+
pop_up = '[role="dialog"] span.cursor-pointer'
23+
sb.click_if_visible(pop_up)
24+
sb.highlight("#block-summary")
25+
sb.click_if_visible(pop_up)
26+
sb.highlight("#block-geolocation")
27+
sb.click_if_visible(pop_up)
28+
sb.sleep(2)
29+
print("Displaying Host Info:")
30+
text = sb.get_text("#block-summary").split("Hosted domains")[0]
31+
rows = text.split("\n")
32+
data = []
33+
for row in rows:
34+
if row.strip() != "":
35+
data.append(row.strip())
36+
print("\n".join(data).replace('\n"', ' "'))
37+
print("\nDisplaying GeoLocation Info:")
38+
text = sb.get_text("#block-geolocation")
39+
text = text.split("IP Geolocation data")[0]
40+
rows = text.split("\n")
41+
data = []
42+
for row in rows:
43+
if row.strip() != "":
44+
data.append(row.strip())
45+
print("\n".join(data).replace('\n"', ' "'))
46+
sb.sleep(3)
47+
48+
49+
if __name__ == "__main__":
50+
main()

examples/proxy_test.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,22 @@ def test_proxy(self):
1515
self.get_new_driver(page_load_strategy="none")
1616
self.open("https://api.ipify.org/")
1717
ip_address = self.get_text("body")
18+
if "ERR" in ip_address:
19+
raise Exception("Failed to determine IP Address!")
1820
print("\n\nMy IP Address = %s\n" % ip_address)
1921
self.open("https://ipinfo.io/%s" % ip_address)
2022
self.sleep(2)
2123
self.wait_for_text(ip_address, "h1", timeout=20)
2224
self.wait_for_element_present('[href="/signup"]')
2325
self.wait_for_text("Hosted domains", timeout=20)
2426
self.highlight("h1")
27+
pop_up = '[role="dialog"] span.cursor-pointer'
28+
self.click_if_visible(pop_up)
2529
self.highlight("#block-summary")
30+
self.click_if_visible(pop_up)
2631
self.highlight("#block-geolocation")
32+
self.click_if_visible(pop_up)
2733
self.sleep(2)
28-
self.click_if_visible("span.ipinfo-modal__close")
2934
print("Displaying Host Info:")
3035
text = self.get_text("#block-summary").split("Hosted domains")[0]
3136
rows = text.split("\n")

mkdocs_build/requirements.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ pymdown-extensions>=10.15
66
pipdeptree>=2.26.1
77
python-dateutil>=2.8.2
88
Markdown==3.8
9-
click==8.1.8
9+
click==8.2.0
1010
ghp-import==2.1.0
1111
watchdog==6.0.0
1212
cairocffi==1.7.1
1313
pathspec==0.12.1
1414
Babel==2.17.0
1515
paginate==0.5.7
1616
mkdocs==1.6.1
17-
mkdocs-material==9.6.12
17+
mkdocs-material==9.6.13
1818
mkdocs-exclude-search==0.6.6
1919
mkdocs-simple-hooks==0.1.5
2020
mkdocs-material-extensions==1.3.1

requirements.txt

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ pip>=25.0.1;python_version<"3.9"
22
pip>=25.1.1;python_version>="3.9"
33
packaging>=25.0
44
setuptools~=70.2;python_version<"3.10"
5-
setuptools>=80.1.0;python_version>="3.10"
5+
setuptools>=80.4.0;python_version>="3.10"
66
wheel>=0.45.1
77
attrs>=25.3.0
88
certifi>=2025.4.26
9-
exceptiongroup>=1.2.2
9+
exceptiongroup>=1.3.0
1010
websockets~=13.1;python_version<"3.9"
1111
websockets>=15.0.1;python_version>="3.9"
1212
filelock~=3.16.1;python_version<"3.9"
@@ -15,7 +15,7 @@ fasteners>=0.19
1515
mycdp>=1.2.0
1616
pynose>=1.5.4
1717
platformdirs>=4.3.6;python_version<"3.9"
18-
platformdirs>=4.3.7;python_version>="3.9"
18+
platformdirs>=4.3.8;python_version>="3.9"
1919
typing-extensions>=4.13.2
2020
sbvirtualdisplay>=1.4.0
2121
MarkupSafe==2.1.5;python_version<"3.9"
@@ -57,7 +57,7 @@ pytest-html==4.0.2
5757
pytest-metadata==3.1.1
5858
pytest-ordering==0.6
5959
pytest-rerunfailures==14.0;python_version<"3.9"
60-
pytest-rerunfailures==15.0;python_version>="3.9"
60+
pytest-rerunfailures==15.1;python_version>="3.9"
6161
pytest-xdist==3.6.1
6262
parameterized==0.9.0
6363
behave==1.2.6

seleniumbase/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.38.0"
2+
__version__ = "4.38.1"

seleniumbase/core/browser_launcher.py

+29-3
Original file line numberDiff line numberDiff line change
@@ -1921,6 +1921,7 @@ def _add_chrome_proxy_extension(
19211921
proxy_string,
19221922
proxy_user,
19231923
proxy_pass,
1924+
proxy_scheme,
19241925
proxy_bypass_list=None,
19251926
zip_it=True,
19261927
multi_proxy=False,
@@ -1939,7 +1940,11 @@ def _add_chrome_proxy_extension(
19391940
proxy_zip_lock = fasteners.InterProcessLock(PROXY_ZIP_LOCK)
19401941
with proxy_zip_lock:
19411942
proxy_helper.create_proxy_ext(
1942-
proxy_string, proxy_user, proxy_pass, bypass_list
1943+
proxy_string,
1944+
proxy_user,
1945+
proxy_pass,
1946+
proxy_scheme,
1947+
bypass_list,
19431948
)
19441949
proxy_zip = proxy_helper.PROXY_ZIP_PATH
19451950
chrome_options.add_extension(proxy_zip)
@@ -1950,6 +1955,7 @@ def _add_chrome_proxy_extension(
19501955
proxy_string,
19511956
proxy_user,
19521957
proxy_pass,
1958+
proxy_scheme,
19531959
bypass_list,
19541960
zip_it=False,
19551961
)
@@ -1968,7 +1974,11 @@ def _add_chrome_proxy_extension(
19681974
_set_proxy_filenames()
19691975
if not os.path.exists(proxy_helper.PROXY_ZIP_PATH):
19701976
proxy_helper.create_proxy_ext(
1971-
proxy_string, proxy_user, proxy_pass, bypass_list
1977+
proxy_string,
1978+
proxy_user,
1979+
proxy_pass,
1980+
proxy_scheme,
1981+
bypass_list,
19721982
)
19731983
proxy_zip = proxy_helper.PROXY_ZIP_PATH
19741984
chrome_options.add_extension(proxy_zip)
@@ -1984,6 +1994,7 @@ def _add_chrome_proxy_extension(
19841994
proxy_string,
19851995
proxy_user,
19861996
proxy_pass,
1997+
proxy_scheme,
19871998
bypass_list,
19881999
zip_it=False,
19892000
)
@@ -2058,6 +2069,7 @@ def _set_chrome_options(
20582069
proxy_auth,
20592070
proxy_user,
20602071
proxy_pass,
2072+
proxy_scheme,
20612073
proxy_bypass_list,
20622074
proxy_pac_url,
20632075
multi_proxy,
@@ -2362,6 +2374,7 @@ def _set_chrome_options(
23622374
proxy_string,
23632375
proxy_user,
23642376
proxy_pass,
2377+
proxy_scheme,
23652378
proxy_bypass_list,
23662379
zip_it,
23672380
multi_proxy,
@@ -2381,6 +2394,7 @@ def _set_chrome_options(
23812394
None,
23822395
proxy_user,
23832396
proxy_pass,
2397+
proxy_scheme,
23842398
proxy_bypass_list,
23852399
zip_it,
23862400
multi_proxy,
@@ -2992,6 +3006,7 @@ def get_driver(
29923006
proxy_auth = False
29933007
proxy_user = None
29943008
proxy_pass = None
3009+
proxy_scheme = "http"
29953010
if proxy_string:
29963011
username_and_password = None
29973012
if "@" in proxy_string:
@@ -3015,7 +3030,9 @@ def get_driver(
30153030
"that has authentication! (If using a proxy server "
30163031
"without auth, Chrome, Edge, or Firefox may be used.)"
30173032
)
3018-
proxy_string = proxy_helper.validate_proxy_string(proxy_string)
3033+
proxy_string, proxy_scheme = proxy_helper.validate_proxy_string(
3034+
proxy_string, keep_scheme=True
3035+
)
30193036
if proxy_string and proxy_user and proxy_pass:
30203037
proxy_auth = True
30213038
elif proxy_pac_url:
@@ -3104,6 +3121,7 @@ def get_driver(
31043121
proxy_auth,
31053122
proxy_user,
31063123
proxy_pass,
3124+
proxy_scheme,
31073125
proxy_bypass_list,
31083126
proxy_pac_url,
31093127
multi_proxy,
@@ -3164,6 +3182,7 @@ def get_driver(
31643182
proxy_auth,
31653183
proxy_user,
31663184
proxy_pass,
3185+
proxy_scheme,
31673186
proxy_bypass_list,
31683187
proxy_pac_url,
31693188
multi_proxy,
@@ -3224,6 +3243,7 @@ def get_remote_driver(
32243243
proxy_auth,
32253244
proxy_user,
32263245
proxy_pass,
3246+
proxy_scheme,
32273247
proxy_bypass_list,
32283248
proxy_pac_url,
32293249
multi_proxy,
@@ -3364,6 +3384,7 @@ def get_remote_driver(
33643384
proxy_auth,
33653385
proxy_user,
33663386
proxy_pass,
3387+
proxy_scheme,
33673388
proxy_bypass_list,
33683389
proxy_pac_url,
33693390
multi_proxy,
@@ -3540,6 +3561,7 @@ def get_remote_driver(
35403561
proxy_auth,
35413562
proxy_user,
35423563
proxy_pass,
3564+
proxy_scheme,
35433565
proxy_bypass_list,
35443566
proxy_pac_url,
35453567
multi_proxy,
@@ -3661,6 +3683,7 @@ def get_local_driver(
36613683
proxy_auth,
36623684
proxy_user,
36633685
proxy_pass,
3686+
proxy_scheme,
36643687
proxy_bypass_list,
36653688
proxy_pac_url,
36663689
multi_proxy,
@@ -4325,6 +4348,7 @@ def get_local_driver(
43254348
proxy_string,
43264349
proxy_user,
43274350
proxy_pass,
4351+
proxy_scheme,
43284352
proxy_bypass_list,
43294353
zip_it=True,
43304354
multi_proxy=multi_proxy,
@@ -4341,6 +4365,7 @@ def get_local_driver(
43414365
None,
43424366
proxy_user,
43434367
proxy_pass,
4368+
proxy_scheme,
43444369
proxy_bypass_list,
43454370
zip_it=True,
43464371
multi_proxy=multi_proxy,
@@ -4531,6 +4556,7 @@ def get_local_driver(
45314556
proxy_auth,
45324557
proxy_user,
45334558
proxy_pass,
4559+
proxy_scheme,
45344560
proxy_bypass_list,
45354561
proxy_pac_url,
45364562
multi_proxy,

seleniumbase/core/proxy_helper.py

+23-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717

1818

1919
def create_proxy_ext(
20-
proxy_string, proxy_user, proxy_pass, bypass_list=None, zip_it=True
20+
proxy_string,
21+
proxy_user,
22+
proxy_pass,
23+
proxy_scheme="http",
24+
bypass_list=None,
25+
zip_it=True,
2126
):
2227
"""Implementation of https://stackoverflow.com/a/35293284 for
2328
https://stackoverflow.com/questions/12848327/
@@ -40,7 +45,7 @@ def create_proxy_ext(
4045
""" mode: "fixed_servers",\n"""
4146
""" rules: {\n"""
4247
""" singleProxy: {\n"""
43-
""" scheme: "http",\n"""
48+
""" scheme: "%s",\n"""
4449
""" host: "%s",\n"""
4550
""" port: parseInt("%s")\n"""
4651
""" },\n"""
@@ -63,7 +68,12 @@ def create_proxy_ext(
6368
""" {urls: ["<all_urls>"]},\n"""
6469
""" ['blocking']\n"""
6570
""");""" % (
66-
proxy_host, proxy_port, bypass_list, proxy_user, proxy_pass
71+
proxy_scheme,
72+
proxy_host,
73+
proxy_port,
74+
bypass_list,
75+
proxy_user,
76+
proxy_pass,
6777
)
6878
)
6979
else:
@@ -157,11 +167,18 @@ def remove_proxy_zip_if_present():
157167
os.remove(PROXY_ZIP_LOCK)
158168

159169

160-
def validate_proxy_string(proxy_string):
170+
def validate_proxy_string(proxy_string, keep_scheme=False):
161171
if proxy_string in proxy_list.PROXY_LIST.keys():
162172
proxy_string = proxy_list.PROXY_LIST[proxy_string]
163173
if not proxy_string:
164174
return None
175+
proxy_scheme = "http"
176+
if proxy_string.startswith("https://"):
177+
proxy_scheme = "https"
178+
elif proxy_string.startswith("socks4://"):
179+
proxy_scheme = "socks4"
180+
elif proxy_string.startswith("socks5://"):
181+
proxy_scheme = "socks5"
165182
valid = False
166183
val_ip = re.match(
167184
r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$", proxy_string
@@ -198,6 +215,8 @@ def validate_proxy_string(proxy_string):
198215
if not valid:
199216
__display_proxy_warning(proxy_string)
200217
proxy_string = None
218+
if keep_scheme:
219+
return (proxy_string, proxy_scheme)
201220
return proxy_string
202221

203222

seleniumbase/undetected/cdp_driver/cdp_util.py

+7
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ def __add_chrome_proxy_extension(
191191
proxy_string,
192192
proxy_user,
193193
proxy_pass,
194+
proxy_scheme="http",
194195
proxy_bypass_list=None,
195196
multi_proxy=False,
196197
):
@@ -210,6 +211,7 @@ def __add_chrome_proxy_extension(
210211
proxy_string,
211212
proxy_user,
212213
proxy_pass,
214+
proxy_scheme,
213215
bypass_list,
214216
zip_it=False,
215217
)
@@ -230,6 +232,7 @@ def __add_chrome_proxy_extension(
230232
proxy_string,
231233
proxy_user,
232234
proxy_pass,
235+
proxy_scheme,
233236
bypass_list,
234237
zip_it=False,
235238
)
@@ -312,11 +315,15 @@ async def start(
312315
proxy_user = user_with_pass.split(":")[0]
313316
proxy_pass = user_with_pass.split(":")[1]
314317
proxy_string = proxy.split("@")[1]
318+
proxy_string, proxy_scheme = proxy_helper.validate_proxy_string(
319+
proxy_string, keep_scheme=True
320+
)
315321
extension_dir = __add_chrome_proxy_extension(
316322
extension_dir,
317323
proxy_string,
318324
proxy_user,
319325
proxy_pass,
326+
proxy_scheme,
320327
)
321328
if ad_block:
322329
incognito = False

0 commit comments

Comments
 (0)