when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
added google-chrome-stable to the list, as some distro's have this name.
Chrome(advanced_elements)bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
**driver_executable_path=None**
also known as executable_path
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
**browser_executable_path=None**
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
**advanced_elements=False**
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2",element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
changed the way how patcher works (for those using multiple sessions/processes).
when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
find_chrome_executable:
added google-chrome-stable to the list, as some distro's have this name.
advanced_webelements: bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
Chrome() parameters
driver_executable_path=None
( = executable_path )
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
browser_executable_path=None
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
advanced_elements=False
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
changed the way how patcher works (for those using multiple sessions/processes).
when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
find_chrome_executable:
added google-chrome-stable to the list, as some distro's have this name.
advanced_webelements: bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
Chrome() parameters
driver_executable_path=None
( = executable_path )
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
browser_executable_path=None
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
advanced_elements=False
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
changed the way how patcher works (for those using multiple sessions/processes).
when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
find_chrome_executable:
added google-chrome-stable to the list, as some distro's have this name.
advanced_webelements: bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
Chrome() parameters
driver_executable_path=None
( = executable_path )
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
browser_executable_path=None
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
advanced_elements=False
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
changed the way how patcher works (for those using multiple sessions/processes).
when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
find_chrome_executable:
added google-chrome-stable to the list, as some distro's have this name.
advanced_webelements: bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
Chrome() parameters
driver_executable_path=None
( = executable_path )
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
browser_executable_path=None
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
advanced_elements=False
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
changed the way how patcher works (for those using multiple sessions/processes).
when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
find_chrome_executable:
added google-chrome-stable to the list, as some distro's have this name.
advanced_webelements: bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
Chrome() parameters
driver_executable_path=None
( = executable_path )
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
browser_executable_path=None
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
advanced_elements=False
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
changed the way how patcher works (for those using multiple sessions/processes).
when not specifying a executable_path (the default, and recommended!), the filename
gets randomized to <somehex>_chromedriver[.exe]. this should fix the issue for multiprocessing
(although Chrome/driver itself has restrictions in this as well, see it using processhacker).
As i told before, webdriver is a purely io-based operation which only sends and pulls data. multiprocessing/threading isn't going to help much. You'd better use asyncio.)
find_chrome_executable:
added google-chrome-stable to the list, as some distro's have this name.
advanced_webelements: bool, optional, default: False
makes it easier to recognize elements like you know them from html/browser inspection, especially when working in an interactive environment
default webelement repr:
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
advanced webelement repr
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
note: when retrieving large amounts of elements ( example: find_elements_by_tag("*") ) and **print** them, it does take a little more time for all the repr's to fetch
Chrome() parameters
driver_executable_path=None
( = executable_path )
if you really need to specify your own chromedriver binary.
(don't log issues when you are not using the default. the downloading per session happens for a reason. remember this is a detection-focussed fork)
browser_executable_path=None
( = browser binary path )
to specify your browser in case you use exotic locations instead of the more default install folders
advanced_elements=False
if set to True, webelements get a nicer REPR showing. this is very convenient when working
interactively (like ipython for example).
<WebElement(<a class="mobile-show-inline-block mc-update-infos init-ok" href="#" id="main-cat-switcher-mobile">)>
instead of
<selenium.webdriver.remote.webelement.WebElement (session="85ff0f671512fa535630e71ee951b1f2", element="6357cb55-92c3-4c0f-9416-b174f9c1b8c4")>
QUICK TEST FOR UNDETECTED-CHROMEDRIVER TO CHECK IF CLOUDFLARE IAUAM CAN BE PASSED
To make it as clean as possible without interfering packages or plugins:
- this creates a new python virtual environment
- installs undetected chromedriver
- executes a test
- cleans up the virtual environment
simplify specifying a custom user_data_dir by passing it directly to the constructor.
however if a user_data_dir is specified in the options object, the one in options will take precedence.
-----------
this version is for test purposes only and contains breaking changes
-----------
- v2 is now the "main/default" module. usage:
import undetected_chromedriver as uc
driver = uc.Chrome()
driver.get('https://nowsecure.nl')
- The above is the README for this version. or use the regular instructions, but
skip the `with` black magic and skip references to v2.
- v1 moved to _compat for now.
- fixed wrong dependancies
- ~~~~ added "new" anti-detection mechanic ~~~~
- the above ^^ makes all recent changes and additions obsolete
- Removed ChromeOptions black magic to fix compatiblity issues
- restored .get() to (near) original.
- most changes from 3.0.4 to 3.0.6 are obsolete, as t
- no `with` statements needed anymore, although it will still
work for the sake of backward-compatibility.
- no sleeps, stop-start-sessions, delays, or async cdp black magic!
- this will solve a lot of other "issues" as well.
- test success to date: 100%
- just to mention it another time, since some people have hard time reading:
headless is still WIP. Raising issues is needless
*3.0.0
added lots of features and bugfixes
- You can now subscribe to Chrome Devtools Protocol Events like networking.
- splitted the project up in seperate modules now
- fixed locale (accept-language)
- you can enter your user-data-folder as property of
ChromeOptions() now.
- The ChromeOptions had a makeover, and i took the one from alpha 4,
people having troubles with mobile emulation and other bullshit,
can try again now.
- fixed the logic where sometimes options did not
respect the given values
- for headless (though still not supperted for undetectability),
added some real cool features which need to be set in
the options object):
defaults:
emulate_touch = True
mock_permissions = True # headless had notificationpermissions
setup in a distinguisable way.
mock_chrome_global = False
mock_canvas_fp = True # patch fingerprint
EXTENSIONS ARE NOT SUPPORTED BY CHROME IN HEADLESS MODE
YET. IF YOU WANT TO USE THEM, CREATE A PROFILE AND INSTALL
EXTENSIONS BY USING A REGULAR CHROME SESSION FIRST.
ALSO LOGIN TO GMAIL WHILE YOU'RE ON A GENUINE SESSION.
WHEN FINISHED, COPY THE USERDATA FOLDER OF CHROME TO SOME KNOWN
LOCATION (and make maye 2 copies?). BY HAVING GMAIL LOGGED IN
FIXES ALSO THE UNSAFE BROWSER MESSAGE FROM GOOGLE (AT LEAST FOR
ME IT WORKS)
* 2.2.2
* fixed a number of bugs
- specifying custom profile
- specifying custom binary path
- downloading, patching and storing now (if not explicity specified)
happens in a writable folder, instead of the current working dir.
Committer: UltrafunkAmsterdam <UltrafunkAmsterdam@github>
* tidy up
* uncomment block
* - support for specifying and reusing the user profile folder.
if a user-data-dir is specified, that folder will NOT be
deleted on exit.
example:
options.add_argument('--user-data-dir=c:\\temp')
- uses a platform specific app data folder to store driver instead
of the current workdir.
- impoved headless mode. fixed detection by notification perms.
- eliminates the "restore tabs" notification at startup
- added methods find_elements_by_text and find_element_by_text
- updated docs (partly)
-known issues:
- extensions not running. this is due to the inner workings
of chromedriver. still working on this.
- driver window is not always closing along with a program exit.
- MacOS: startup nag notifications. might be solved by
re(using) a profile directory.
- known stuff:
- some specific use cases, network conditions or behaviour
can cause being detected.
* Squashed commit of the following:
commit 7ce8e7a236cbee770cb117145d4bf6dc245b936a
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Fri Apr 30 18:22:39 2021 +0200
readme change
commit f214dcf33f26f8b35616d7b61cf6dee656596c3f
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Fri Apr 30 18:18:09 2021 +0200
- make sure options cannot be reused as it will
cause double and conflicting arguments to chrome
- support for specifying and reusing the user profile folder.
if a user-data-dir is specified, that folder will NOT be
deleted on exit.
example:
options.add_argument('--user-data-dir=c:\\temp')
- uses a platform specific app data folder to store driver instead
of the current workdir.
- impoved headless mode. fixed detection by notification perms.
- eliminates the "restore tabs" notification at startup
- added methods find_elements_by_text and find_element_by_text
- updated docs (partly)
-known issues:
- extensions not running. this is due to the inner workings
of chromedriver. still working on this.
- driver window is not always closing along with a program exit.
- MacOS: startup nag notifications. might be solved by
re(using) a profile directory.
- known stuff:
- some specific use cases, network conditions or behaviour
can cause being detected.
* 2.2.2
* fixed a number of bugs
- specifying custom profile
- specifying custom binary path
- downloading, patching and storing now (if not explicity specified)
happens in a writable folder, instead of the current working dir.
Committer: UltrafunkAmsterdam <UltrafunkAmsterdam@github>
* tidy up
* uncomment block
* - support for specifying and reusing the user profile folder.
if a user-data-dir is specified, that folder will NOT be
deleted on exit.
example:
options.add_argument('--user-data-dir=c:\\temp')
- uses a platform specific app data folder to store driver instead
of the current workdir.
- impoved headless mode. fixed detection by notification perms.
- eliminates the "restore tabs" notification at startup
- added methods find_elements_by_text and find_element_by_text
- updated docs (partly)
-known issues:
- extensions not running. this is due to the inner workings
of chromedriver. still working on this.
- driver window is not always closing along with a program exit.
- MacOS: startup nag notifications. might be solved by
re(using) a profile directory.
- known stuff:
- some specific use cases, network conditions or behaviour
can cause being detected.
* Squashed commit of the following:
commit 7ce8e7a236cbee770cb117145d4bf6dc245b936a
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Fri Apr 30 18:22:39 2021 +0200
readme change
commit f214dcf33f26f8b35616d7b61cf6dee656596c3f
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Fri Apr 30 18:18:09 2021 +0200
- make sure options cannot be reused as it will
cause double and conflicting arguments to chrome
commit cf059a638c
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Thu Apr 29 12:54:49 2021 +0200
- support for specifying and reusing the user profile folder.
if a user-data-dir is specified, that folder will NOT be
deleted on exit.
example:
options.add_argument('--user-data-dir=c:\\temp')
- uses a platform specific app data folder to store driver instead
of the current workdir.
- impoved headless mode. fixed detection by notification perms.
- eliminates the "restore tabs" notification at startup
- added methods find_elements_by_text and find_element_by_text
- updated docs (partly)
-known issues:
- extensions not running. this is due to the inner workings
of chromedriver. still working on this.
- driver window is not always closing along with a program exit.
- MacOS: startup nag notifications. might be solved by
re(using) a profile directory.
- known stuff:
- some specific use cases, network conditions or behaviour
can cause being detected.
commit b40d23c649
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Tue Apr 27 20:41:18 2021 +0200
uncomment block
commit d99809c8c6
Author: ultrafunkamsterdam <info@blackhat-security.nl>
Date: Tue Apr 27 20:19:51 2021 +0200
tidy up
* .
* 2.2.7
Co-authored-by: ultrafunkamsterdam <info@blackhat-security.nl>
credits to @boganfoo for this excellent find!
- removed `enable_console_log`
- reverted back to storing chromedriver binary in current workdir after several reports of users entire project folder being deleted (sorry for that btw).
- some code cleanup
- added a fix for useragent in headless mode in v2 (which reported 'Headless'). still headless mode in v2 is under construction and not fully functional.
- reverted back to storing chromedriver binary in current workdir after several reports of users entire project folder being deleted (sorry for that btw).
- some code cleanup
- added a fix for useragent in headless mode in v2 (which reported 'Headless'). still headless mode in v2 is under construction and not fully functional.
- added a keyword argument to the Chrome constructor: 'emulate_touch' which, when set to True will report presense of a touch(screen/device). This is mainly for bet365 detections. Otherwise i would not recommend setting it.
credits to @boganfoo for this excellent find!
- prevent custom data dir to be automatically removed.
- remove the driver executable cleanup function, it is deleted at initialization anyway so it was double trouble.
- reverted back to having chromedriver in the CWD instead of a temp folder
@untested
todo: test