From f7306fad3e59945d57b9a1b962f6a8a718f0004e Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 23 Dec 2021 17:10:04 +0100 Subject: [PATCH 1/4] bugfix spawn --- undetected_chromedriver/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/undetected_chromedriver/__init__.py b/undetected_chromedriver/__init__.py index 84a5f90..0a7afa7 100644 --- a/undetected_chromedriver/__init__.py +++ b/undetected_chromedriver/__init__.py @@ -536,7 +536,8 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): def quit(self): logger.debug("closing webdriver") - self.service.process.kill() + if hasattr(self, 'service') and getattr(self.service, 'process', None): + self.service.process.kill() try: if self.reactor and isinstance(self.reactor, Reactor): logger.debug("shutting down reactor") From f9e9e772185b00d937c6932bdc71368fddde0daa Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 23 Dec 2021 18:23:25 +0100 Subject: [PATCH 2/4] bug fix --- undetected_chromedriver/__init__.py | 41 ++++++++++++----------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/undetected_chromedriver/__init__.py b/undetected_chromedriver/__init__.py index 0a7afa7..9d41796 100644 --- a/undetected_chromedriver/__init__.py +++ b/undetected_chromedriver/__init__.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 from __future__ import annotations +import subprocess + """ 888 888 d8b @@ -16,7 +18,7 @@ by UltrafunkAmsterdam (https://github.com/ultrafunkamsterdam) """ -__version__ = "3.1.0" +__version__ = "3.1.2" import json import logging @@ -111,6 +113,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): version_main=None, patcher_force_close=False, suppress_welcome=True, + detached_process=True, debug=False, **kw ): @@ -336,7 +339,17 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): if not desired_capabilities: desired_capabilities = options.to_capabilities() - self.browser_pid = start_detached(options.binary_location, *options.arguments) + if not detached_process: + browser = subprocess.Popen( + [options.binary_location, *options.arguments], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + close_fds=IS_POSIX, + ) + self.browser_pid = browser.pid + else: + self.browser_pid = start_detached(options.binary_location, *options.arguments) super(Chrome, self).__init__( executable_path=patcher.executable_path, @@ -363,6 +376,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): self._configure_headless() def __getattribute__(self, item): + if not super().__getattribute__("debug"): return super().__getattribute__(item) else: @@ -381,15 +395,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): return newfunc return original - # @property - # def switch_to(self): - # def callback(): - # self.get(self.current_url) - # try: - # return super().switch_to - # finally: - # threading.Timer(.1, callback).start() - def _configure_headless(self): orig_get = self.get @@ -537,7 +542,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): def quit(self): logger.debug("closing webdriver") if hasattr(self, 'service') and getattr(self.service, 'process', None): - self.service.process.kill() + self.service.process.kill() try: if self.reactor and isinstance(self.reactor, Reactor): logger.debug("shutting down reactor") @@ -547,8 +552,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): try: logger.debug("killing browser") os.kill(self.browser_pid, 15) - # self.browser.terminate() - # self.browser.wait(1) except TimeoutError as e: logger.debug(e, exc_info=True) @@ -584,19 +587,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): self.quit() def __enter__(self): - try: - curframe = inspect.currentframe() - callframe = inspect.getouterframes(curframe, 2) - caller = callframe[1][3] - logging.getLogger(__name__).debug("__enter__ caller: %s" % caller) - if caller == "get": - return - except (AttributeError, ValueError, KeyError, OSError) as e: - logging.getLogger(__name__).debug(e) return self def __exit__(self, exc_type, exc_val, exc_tb): - self.service.stop() time.sleep(self._delay) self.service.start() From 3bf4cdf7a9c51078bccd4dd762da99f550b42035 Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 24 Dec 2021 15:31:51 +0100 Subject: [PATCH 3/4] 3.1.2 - some 'bug' fixes --- setup.py | 8 +++++--- undetected_chromedriver/__init__.py | 27 +++++++++++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/setup.py b/setup.py index 3576b98..239d588 100644 --- a/setup.py +++ b/setup.py @@ -46,10 +46,11 @@ setup( description="""\ selenium.webdriver.Chrome replacement wiht compatiblity for Brave, and other Chromium baed browsers. not triggered by CloudFlare/Imperva/hCaptcha and such. - NOTE: results may vary due to many factors. No guarantees are given, except for ongoing efforts in understanding detection algorithms. """, - long_description=open(os.path.join(dirname, "README.md"),encoding="utf-8").read(), + + long_description=open(os.path.join(dirname, "README.md"), encoding="utf-8").read(), + long_description_content_type="text/markdown", classifiers=[ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", @@ -57,6 +58,7 @@ setup( "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.10" + "Programming Language :: Python :: 3.11", ], ) diff --git a/undetected_chromedriver/__init__.py b/undetected_chromedriver/__init__.py index 9d41796..d89ab39 100644 --- a/undetected_chromedriver/__init__.py +++ b/undetected_chromedriver/__init__.py @@ -113,7 +113,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): version_main=None, patcher_force_close=False, suppress_welcome=True, - detached_process=True, + no_subprocess=True, debug=False, **kw ): @@ -185,6 +185,23 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): now, in case you are nag-fetishist, or a diagnostics data feeder to google, you can set this to False. Note: if you don't handle the nag screen in time, the browser loses it's connection and throws an Exception. + use_subprocess: bool, optional , default: False, + + False (the default) makes sure Chrome will get it's own process (so no subprocess of chromedriver.exe or python + This fixes a LOT of issues, like multithreaded run, but mst importantly. shutting corectly after + program exits or using .quit() + + unfortunately, there is always an edge case in which one would like to write an single script with the only contents being: + --start script-- + import undetected_chromedriver as uc + d = uc.Chrome() + d.get('https://somesite/') + ---end script -- + + and will be greeted with an error, since the program exists before chrome has a change to launch. + in that case you can set this to `True`. The browser will start via subprocess, and will keep running most of times. + ! setting it to True comes with NO support when being detected. ! + """ self.debug = debug patcher = Patcher( @@ -339,7 +356,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): if not desired_capabilities: desired_capabilities = options.to_capabilities() - if not detached_process: + if not use_subprocess: + self.browser_pid = start_detached(options.binary_location, *options.arguments) + else: browser = subprocess.Popen( [options.binary_location, *options.arguments], stdin=subprocess.PIPE, @@ -348,8 +367,8 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): close_fds=IS_POSIX, ) self.browser_pid = browser.pid - else: - self.browser_pid = start_detached(options.binary_location, *options.arguments) + + super(Chrome, self).__init__( executable_path=patcher.executable_path, From 1245e160c546f6af86978fc2f0dac90f6ba66bac Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 24 Dec 2021 14:51:15 +0000 Subject: [PATCH 4/4] Update __init__.py --- undetected_chromedriver/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/undetected_chromedriver/__init__.py b/undetected_chromedriver/__init__.py index d89ab39..e453432 100644 --- a/undetected_chromedriver/__init__.py +++ b/undetected_chromedriver/__init__.py @@ -113,7 +113,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): version_main=None, patcher_force_close=False, suppress_welcome=True, - no_subprocess=True, + use_subprocess=False, debug=False, **kw ):