corrected find_chrome_executable to work in MacOS

This commit is contained in:
unknown 2021-01-17 20:31:22 +01:00
parent 62684ac898
commit c8f28b1a70
3 changed files with 45 additions and 20 deletions

View File

@ -1,4 +1,4 @@
# undetected_chromedriver # undetected_chromedriver #
https://github.com/ultrafunkamsterdam/undetected-chromedriver https://github.com/ultrafunkamsterdam/undetected-chromedriver
@ -45,6 +45,7 @@ uc.install()
from selenium.webdriver import Chrome from selenium.webdriver import Chrome
driver = Chrome() driver = Chrome()
driver.get('https://distilnetworks.com') driver.get('https://distilnetworks.com')
``` ```

View File

@ -16,7 +16,7 @@ from setuptools import setup
setup( setup(
name="undetected-chromedriver", name="undetected-chromedriver",
version="2.0.B0", version="2.0.0",
packages=["undetected_chromedriver"], packages=["undetected_chromedriver"],
install_requires=["selenium",], install_requires=["selenium",],
url="https://github.com/ultrafunkamsterdam/undetected-chromedriver", url="https://github.com/ultrafunkamsterdam/undetected-chromedriver",

View File

@ -46,6 +46,8 @@ import tempfile
import threading import threading
import time import time
import zipfile import zipfile
import atexit
import contextlib
from distutils.version import LooseVersion from distutils.version import LooseVersion
from urllib.request import urlopen, urlretrieve from urllib.request import urlopen, urlretrieve
@ -54,11 +56,10 @@ import selenium.webdriver.chrome.webdriver
import selenium.webdriver.common.service import selenium.webdriver.common.service
import selenium.webdriver.remote.webdriver import selenium.webdriver.remote.webdriver
__all__ = ('Chrome', 'ChromeOptions', 'Patcher', 'find_chrome_executable') __all__ = ("Chrome", "ChromeOptions", "Patcher", "find_chrome_executable")
IS_POSIX = sys.platform.startswith(("darwin", "cygwin", "linux")) IS_POSIX = sys.platform.startswith(("darwin", "cygwin", "linux"))
logger = logging.getLogger("uc") logger = logging.getLogger("uc")
@ -75,6 +76,8 @@ def find_chrome_executable():
for item in os.environ.get("PATH").split(os.pathsep): for item in os.environ.get("PATH").split(os.pathsep):
for subitem in ("google-chrome", "chromium", "chromium-browser"): for subitem in ("google-chrome", "chromium", "chromium-browser"):
candidates.add(os.sep.join((item, subitem))) candidates.add(os.sep.join((item, subitem)))
if 'darwin' in sys.platform:
candidates.update(["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"])
else: else:
for item in map( for item in map(
os.environ.get, ("PROGRAMFILES", "PROGRAMFILES(X86)", "LOCALAPPDATA") os.environ.get, ("PROGRAMFILES", "PROGRAMFILES(X86)", "LOCALAPPDATA")
@ -91,7 +94,16 @@ def find_chrome_executable():
class Chrome(selenium.webdriver.chrome.webdriver.WebDriver): class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
__doc__ = selenium.webdriver.remote.webdriver.WebDriver.__doc__
__doc__ = """\
--------------------------------------------------------------------------
NOTE:
Chrome has everything included to work out of the box.
it does not `need` customizations.
any customizations MAY lead to trigger bot migitation systems.
--------------------------------------------------------------------------
""" + selenium.webdriver.remote.webdriver.WebDriver.__doc__
_instances = set() _instances = set()
@ -113,6 +125,7 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
p = Patcher(target_path=executable_path) p = Patcher(target_path=executable_path)
p.auto(False) p.auto(False)
self._patcher = p
self.factor = factor self.factor = factor
self.delay = delay self.delay = delay
self.port = port self.port = port
@ -143,9 +156,6 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
if not options.binary_location: if not options.binary_location:
options.binary_location = find_chrome_executable() options.binary_location = find_chrome_executable()
if not IS_POSIX:
options.set_capability("platformName", "Windows")
if not desired_capabilities: if not desired_capabilities:
desired_capabilities = options.to_capabilities() desired_capabilities = options.to_capabilities()
@ -265,8 +275,11 @@ class Patcher(object):
url_repo = "https://chromedriver.storage.googleapis.com" url_repo = "https://chromedriver.storage.googleapis.com"
def __init__(self, target_path=None, force=False, version_main: int = 0): def __init__(self, target_path=None, force=False, version_main: int = 0):
if target_path and not IS_POSIX:
if not target_path[-4] == ".exe": if not target_path:
target_path = os.path.join(tempfile.gettempdir(), 'undetected_chromedriver', 'chromedriver')
if not IS_POSIX:
if not target_path[-4:] == ".exe":
target_path += ".exe" target_path += ".exe"
self.force = force self.force = force
@ -280,7 +293,7 @@ class Patcher(object):
self.version_main = version_main self.version_main = version_main
self.version_full = None self.version_full = None
def auto(self, force=True): def auto(self, force=False):
try: try:
os.unlink(self.target_path) os.unlink(self.target_path)
except PermissionError: except PermissionError:
@ -346,8 +359,13 @@ class Patcher(object):
:return: path to unpacked executable :return: path to unpacked executable
""" """
logger.debug("unzipping %s" % self.zipname) logger.debug("unzipping %s" % self.zipname)
with zipfile.ZipFile(self.zipname) as zf: try:
zf.extract(self.exename, os.path.abspath(os.path.dirname(self.target_path))) os.makedirs(os.path.dirname(self.target_path), mode=0o755)
except OSError:
pass
with zipfile.ZipFile(self.zipname, mode='r') as zf:
zf.extract(self.exename)
os.rename(self.exename, self.target_path)
os.remove(self.zipname) os.remove(self.zipname)
os.chmod(self.target_path, 0o755) os.chmod(self.target_path, 0o755)
return self.target_path return self.target_path
@ -399,11 +417,14 @@ class Patcher(object):
:return: False if not patched, else True :return: False if not patched, else True
""" """
try:
with io.open(self.target_path, "rb") as fh: with io.open(self.target_path, "rb") as fh:
for line in iter(lambda: fh.readline(), b""): for line in iter(lambda: fh.readline(), b""):
if b"cdc_" in line: if b"cdc_" in line:
return False return False
return True return True
except FileNotFoundError:
return False
def patch_exe(self): def patch_exe(self):
""" """
@ -425,6 +446,9 @@ class Patcher(object):
linect += 1 linect += 1
return linect return linect
def __del__(self):
shutil.rmtree(os.path.dirname(self.target_path), ignore_errors=True)
class ChromeOptions(selenium.webdriver.chrome.webdriver.Options): class ChromeOptions(selenium.webdriver.chrome.webdriver.Options):
pass pass