diff --git a/help_docs/uc_mode.md b/help_docs/uc_mode.md index 09afc044..a6a61a9f 100644 --- a/help_docs/uc_mode.md +++ b/help_docs/uc_mode.md @@ -2,24 +2,22 @@ ## [](https://github.com/seleniumbase/SeleniumBase/) UC Mode 👤 -👤 SeleniumBase UC Mode (Undetected-Chromedriver Mode) allows bots to appear human, which lets them evade detection from anti-bot services that try to block them or trigger CAPTCHAs on various websites. +👤 SeleniumBase UC Mode (Undetected-Chromedriver Mode) allows bots to appear human, which lets them evade detection from anti-bot services that try to block them or trigger CAPTCHAs on various websites. - -
(Watch the UC Mode tutorial on YouTube)
+ +(Watch the UC Mode tutorial on YouTube! ▶️)
-👤 UC Mode is based on [undetected-chromedriver](https://github.com/ultrafunkamsterdam/undetected-chromedriver), but includes multiple updates, fixes, and improvements to support a wider range of features and edge cases: +👤 UC Mode is based on [undetected-chromedriver](https://github.com/ultrafunkamsterdam/undetected-chromedriver), but includes multiple updates, fixes, and improvements to support a wider range of features and edge cases: -* Includes driver version-detection & management. -* Allows mismatched browser/driver versions. -* Automatically changes the user agent to prevent detection. (`HeadlessChrome` to `Chrome`) -* Automatically disconnects chromedriver from Chrome as needed. (And reconnects) +* Automatically changes the user agent to prevent detection. * Supports multithreaded tests in parallel via `pytest-xdist`. -* Adjusts configuration based on the environment. (Linux/Ubuntu vs Windows vs macOS) +* Adjusts some configuration based on the environment. +* Includes driver version-detection and management. * Has options for setting proxy and proxy-with-auth. -* Has ways of adjusting timings from default values. +* Has args for adjusting timings from default values. * Includes multiple ways of structuring test scripts. -👤 Here's an example with the `Driver` manager: +👤 Here's an example with theDriver
manager:
```python
from seleniumbase import Driver
@@ -29,7 +27,7 @@ driver.uc_open_with_reconnect("https://gitlab.com/users/sign_in", 3)
driver.quit()
```
-👤 Here's an example with the `SB` manager: (Has more methods than the `Driver` format, and also quits the driver automatically after the `with` block ends.)
+👤 Here's an example with the SB
manager (which has more methods and functionality than the Driver
format):
```python
from seleniumbase import SB
@@ -53,7 +51,9 @@ with SB(uc=True, test=True) as sb:
sb.post_message("SeleniumBase wasn't detected", duration=4)
```
-👤 Here's an example where clicking the checkbox is required, even for humans: (Commonly seen with forms that are CAPTCHA-protected.)
+👤 Here's an example where clicking the checkbox is required, even for humans:driver
-specific methods added by SeleniumBase for UC Mode: `--uc` / uc=True
```python
driver.uc_open(url)
@@ -110,15 +120,15 @@ driver.uc_click(
driver.uc_switch_to_frame(frame, reconnect_time=None)
```
-(Note that the `reconnect_time` is used to specify how long the driver should be disconnected from Chrome to prevent detection before reconnecting again.)
+(Note that the reconnect_time
is used to specify how long the driver should be disconnected from Chrome to prevent detection before reconnecting again.)
-👤 Since `driver.get(url)` is slower in UC Mode for bypassing detection, use `driver.default_get(url)` for a standard page load instead:
+👤 Since driver.get(url)
is slower in UC Mode for bypassing detection, use driver.default_get(url)
for a standard page load instead:
```python
driver.default_get(url) # Faster, but Selenium can be detected
```
-👤 Here are some examples of using those special UC Mode methods: (Use `self.driver` for `BaseCase` formats. Use `sb.driver` for `SB()` formats):
+👤 Here are some examples of using those special UC Mode methods: (Use self.driver
for BaseCase
formats. Use sb.driver
for SB()
formats):
```python
url = "https://gitlab.com/users/sign_in"
@@ -129,7 +139,7 @@ driver.reconnect(5)
driver.reconnect(timeout=5)
```
-👤 You can also set the `reconnect_time` / `timeout` to `"breakpoint"` as a valid option. This allows the user to perform manual actions (until typing `c` and pressing ENTER to continue from the breakpoint):
+👤 You can also set the reconnect_time
/ timeout
to "breakpoint"
as a valid option. This allows the user to perform manual actions (until typing c
and pressing ENTER
to continue from the breakpoint):
```python
url = "https://gitlab.com/users/sign_in"
@@ -140,13 +150,14 @@ driver.reconnect(timeout="breakpoint")
driver.reconnect("breakpoint")
```
-(Note that while the special UC Mode breakpoint is active, you can't issue Selenium commands to the browser, and the browser can't detect Selenium.)
+(Note that while the special UC Mode
breakpoint is active, you can't use Selenium
commands in the browser, and the browser can't detect Selenium
.)
-👤 The two main causes of getting detected in UC Mode (which are both easily handled) are:
-* Timing. (UC Mode methods let you customize default values that aren't good enough for your environment.)
-* Not using `driver.uc_click(selector)` when you need to remain undetected while clicking something.
+👤 The two main causes of getting detected in UC Mode (which are both easily handled) are:
-👤 To find out if UC Mode will work at all on a specific site (before adjusting for timing), load your site with the following script:
+driver.uc_click(selector)
when you need to remain undetected while clicking something.driver.uc_click
as needed.)
👤 Multithreaded UC Mode:
-If you're using `pytest` for multithreaded UC Mode (which requires using one of the `pytest` [syntax formats](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md)), then all you have to do is set the number of threads when your script runs. (`-n NUM`) Eg:
+If you're using pytest
for multithreaded UC Mode (which requires using one of the pytest
[syntax formats](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md)), then all you have to do is set the number of threads when your script runs. (`-n NUM`) Eg:
```bash
pytest --uc -n 4
```
-(Then `pytest-xdist` is automatically used to spin up and process the threads.)
+(Then pytest-xdist
is automatically used to spin up and process the threads.)
-If you don't want to use `pytest` for multithreading, then you'll need to do a little more work. That involves using a different multithreading library, (eg. `concurrent.futures`), and making sure that thread-locking is done correctly for processes that share resources. To handle that thread-locking, include `sys.argv.append("-n")` in your SeleniumBase file.
+If you don't want to use pytest
for multithreading, then you'll need to do a little more work. That involves using a different multithreading library, (eg. concurrent.futures
), and making sure that thread-locking is done correctly for processes that share resources. To handle that thread-locking, include sys.argv.append("-n")
in your SeleniumBase file.
-Here's a sample script that uses `concurrent.futures` for spinning up multiple processes:
+Here's a sample script that uses concurrent.futures
for spinning up multiple processes:
```python
import sys
@@ -190,3 +201,89 @@ with ThreadPoolExecutor(max_workers=len(urls)) as executor:
for url in urls:
executor.submit(launch_driver, url)
```
+
+--------
+
+👥 Double Duty: Here's an example of handling two CAPTCHAs on one page:
+
+
+
+```python
+from seleniumbase import SB
+
+with SB(uc=True, test=True) as sb:
+ sb.driver.uc_open_with_reconnect("nopecha.com/demo/turnstile", 4.5)
+ sb.switch_to_frame("#example-container5 iframe")
+ sb.driver.uc_click("span.mark", reconnect_time=3)
+
+ if sb.is_element_visible("#example-container0 iframe"):
+ sb.switch_to_frame("#example-container0 iframe")
+ if not sb.is_element_visible("circle.success-circle"):
+ sb.driver.uc_click("span.mark", reconnect_time=3)
+ sb.switch_to_frame("#example-container0 iframe")
+ sb.assert_element("circle.success-circle")
+ sb.switch_to_parent_frame()
+
+ sb.switch_to_frame("#example-container5 iframe")
+ sb.assert_element("svg#success-icon", timeout=3)
+ sb.switch_to_parent_frame()
+ sb.set_messenger_theme(location="top_center")
+ sb.post_message("SeleniumBase wasn't detected!", duration=3)
+```
+
+--------
+
+👤 What makes UC Mode work?
+
+Here are the 3 primary things that UC Mode does to make bots appear human:
+
+chromedriver
to rename Chrome DevTools Console variables.chromedriver
to them.chromedriver
from Chrome during stealthy actions.selenium
for browser automation:
+
+
+
+(If those variables are still there, then websites can easily detect your bots.)
+
+If you launch Chrome using chromedriver
, then there will be settings that make your browser look like a bot. (Instead, UC Mode connects chromedriver
to Chrome after the browser is launched, which makes Chrome look like a normal, human-controlled web browser.)
+
+While chromedriver
is connected to Chrome, website services can detect it. Thankfully, raw selenium
already includes driver.service.stop()
for stopping the chromedriver
service, driver.service.start()
for starting the chromedriver
service, and driver.start_session(capabilities)
for reviving the active browser session with the given capabilities. (SeleniumBase
UC Mode methods automatically use those raw selenium
methods as needed.)
+
+Links to those raw Selenium method definitions have been provided for reference (but you don't need to call those methods directly):
+
+driver.service.stop()
driver.service.start()
driver.start_session(capabilities)
chromedriver
isn't detectable in a browser tab if it never touches that tab. Here's a JS command that lets you open a URL in a new tab (from your current tab):
+
+window.open("URL");
--> (Info: W3Schools)SeleniumBase
UC Mode methods for opening URLs in a stealthy way. Since some websites try to detect if your browser is a bot on the initial page load, this allows you to bypass detection in those situations. After a few seconds (customizable), UC Mode tells chromedriver
to connect to that tab so that automated commands can now be issued. At that point, chromedriver
could be detected if websites are looking for it (but generally websites only look for it during specific events, such as page loads, form submissions, and button clicks).
+
+Avoiding detection while clicking is easy if you schedule your clicks to happen at a future point when the chromedriver
service has been stopped. Here's a JS command that lets you schedule events (such as clicks) to happen in the future:
+
+
+window.setTimeout(function() { SCRIPT }, MS);
--> (Info: W3Schools)SeleniumBase
UC Mode method: driver.uc_click(selector)
so that clicking can be done in a stealthy way. UC Mode schedules your click, disconnects chromedriver
from Chrome, waits a little (customizable), and reconnects.
+
+--------
+
+🏆 Choosing the right CAPTCHA service for your business / website:
+
+
+
+As an ethical hacker / cybersecurity researcher who builds bots that bypass CAPTCHAs for sport, the CAPTCHA service that I personally recommend for keeping bots out is Google's reCAPTCHA:
+
+
+
+Since Google makes Chrome, Google's own reCAPTCHA service has access to more data than other CAPTCHA services (eg. hCaptcha, CloudFlare, DataDome, etc.), and can therefore use that data to make better decisions about whether or not web activity is coming from real humans or automated bots.
+
+--------
+
+
+
+