Merge pull request #418 from ultrafunkamsterdam/bugfix

bugfix
This commit is contained in:
Leon 2021-12-24 14:52:53 +00:00 committed by GitHub
commit 33aa8c3905
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 27 deletions

View File

@ -46,10 +46,11 @@ setup(
description="""\ description="""\
selenium.webdriver.Chrome replacement wiht compatiblity for Brave, and other Chromium baed browsers. selenium.webdriver.Chrome replacement wiht compatiblity for Brave, and other Chromium baed browsers.
not triggered by CloudFlare/Imperva/hCaptcha and such. 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. 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", long_description_content_type="text/markdown",
classifiers=[ classifiers=[
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
@ -57,6 +58,7 @@ setup(
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.10"
"Programming Language :: Python :: 3.11",
], ],
) )

View File

@ -1,6 +1,8 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from __future__ import annotations from __future__ import annotations
import subprocess
""" """
888 888 d8b 888 888 d8b
@ -16,7 +18,7 @@ by UltrafunkAmsterdam (https://github.com/ultrafunkamsterdam)
""" """
__version__ = "3.1.0" __version__ = "3.1.2"
import json import json
import logging import logging
@ -111,6 +113,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
version_main=None, version_main=None,
patcher_force_close=False, patcher_force_close=False,
suppress_welcome=True, suppress_welcome=True,
use_subprocess=False,
debug=False, debug=False,
**kw **kw
): ):
@ -182,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. 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. 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 self.debug = debug
patcher = Patcher( patcher = Patcher(
@ -336,7 +356,19 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if not desired_capabilities: if not desired_capabilities:
desired_capabilities = options.to_capabilities() desired_capabilities = options.to_capabilities()
if not use_subprocess:
self.browser_pid = start_detached(options.binary_location, *options.arguments) self.browser_pid = start_detached(options.binary_location, *options.arguments)
else:
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
super(Chrome, self).__init__( super(Chrome, self).__init__(
executable_path=patcher.executable_path, executable_path=patcher.executable_path,
@ -363,6 +395,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
self._configure_headless() self._configure_headless()
def __getattribute__(self, item): def __getattribute__(self, item):
if not super().__getattribute__("debug"): if not super().__getattribute__("debug"):
return super().__getattribute__(item) return super().__getattribute__(item)
else: else:
@ -381,15 +414,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
return newfunc return newfunc
return original 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): def _configure_headless(self):
orig_get = self.get orig_get = self.get
@ -536,6 +560,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
def quit(self): def quit(self):
logger.debug("closing webdriver") logger.debug("closing webdriver")
if hasattr(self, 'service') and getattr(self.service, 'process', None):
self.service.process.kill() self.service.process.kill()
try: try:
if self.reactor and isinstance(self.reactor, Reactor): if self.reactor and isinstance(self.reactor, Reactor):
@ -546,8 +571,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
try: try:
logger.debug("killing browser") logger.debug("killing browser")
os.kill(self.browser_pid, 15) os.kill(self.browser_pid, 15)
# self.browser.terminate()
# self.browser.wait(1)
except TimeoutError as e: except TimeoutError as e:
logger.debug(e, exc_info=True) logger.debug(e, exc_info=True)
@ -583,19 +606,9 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
self.quit() self.quit()
def __enter__(self): 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 return self
def __exit__(self, exc_type, exc_val, exc_tb): def __exit__(self, exc_type, exc_val, exc_tb):
self.service.stop() self.service.stop()
time.sleep(self._delay) time.sleep(self._delay)
self.service.start() self.service.start()