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()
@ -207,14 +217,14 @@ class Chrome(selenium.webdriver.chrome.webdriver.WebDriver):
(this includes CloudFlare!), and also passes many (this includes CloudFlare!), and also passes many
custom setups (eg: ticketmaster.com), custom setups (eg: ticketmaster.com),
Once you are past the first challenge, a cookie is saved Once you are past the first challenge, a cookie is saved
which (in my tests) also worked for other sites, and lasted which (in my tests) also worked for other sites, and lasted
my entire session! However, to play safe, i'd recommend to just my entire session! However, to play safe, i'd recommend to just
call it once for every new site/domain you navigate to. call it once for every new site/domain you navigate to.
NOTE: mileage may vary! NOTE: mileage may vary!
bad behaviour can still be detected, and this program does not bad behaviour can still be detected, and this program does not
magically "fix" a flagged ip. magically "fix" a flagged ip.
please don't spam issues on github! first look if the issue please don't spam issues on github! first look if the issue
@ -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
""" """
with io.open(self.target_path, "rb") as fh: try:
for line in iter(lambda: fh.readline(), b""): with io.open(self.target_path, "rb") as fh:
if b"cdc_" in line: for line in iter(lambda: fh.readline(), b""):
return False if b"cdc_" in line:
return True return False
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