added to pip package index

This commit is contained in:
ultrafunkamsterdam 2020-09-03 22:12:09 +02:00
parent 97682e3f9f
commit b7685af668
3 changed files with 45 additions and 47 deletions

View File

@ -12,7 +12,7 @@ Automatically downloads the driver binary and patches it.
## Installation ## ## Installation ##
``` ```
pip install git+https://github.com/ultrafunkamsterdam/undetected-chromedriver.git pip install undetected-chromedriver
``` ```
## Usage ## ## Usage ##

View File

@ -1,4 +1,3 @@
""" """
888 888 d8b 888 888 d8b
@ -15,19 +14,24 @@ BY ULTRAFUNKAMSTERDAM (https://github.com/ultrafunkamsterdam)"""
from setuptools import setup from setuptools import setup
setup( setup(
name='undetected-chromedriver', name="undetected-chromedriver",
version='1.3.5', version="1.3.7",
packages=['undetected_chromedriver'], packages=["undetected_chromedriver"],
install_requires=[ install_requires=["selenium",],
'selenium', url="https://github.com/ultrafunkamsterdam/undetected_chromedriver",
license="GPL-3.0",
author="UltrafunkAmsterdam",
author_email="info@blackhat-security.nl",
description="""
Optimized Selenium/Chromedriver drop-in replacement for selenium.webdriver, using the same interface for Chrome and ChromeOptions, but which does NOT trigger anti-bot services like Distil / Imperva / DataDome and such.
All required anti-detection settings are built-in, yet overridable if you\'d really want. Be aware: any customization in settings could potentially trigger detection,
For more information check out the README.""",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
classifiers=[
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
], ],
url='https://github.com/ultrafunkamsterdam/undetected_chromedriver',
license='MIT',
author='UltrafunkAmsterdam',
author_email='',
description='Optimized Selenium Chromedriver patch which does not trigger anti-bot services like Distil Network. '
'Automatically downloads the driver binary and patches it.'
) )

View File

@ -30,23 +30,23 @@ from selenium.webdriver import ChromeOptions as _ChromeOptions
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
__IS_PATCHED__ = 0 __IS_PATCHED__ = 0
TARGET_VERSION = 0 TARGET_VERSION = 0
class Chrome: class Chrome:
def __new__(cls, *args, **kwargs): def __new__(cls, *args, **kwargs):
if not ChromeDriverManager.installed: if not ChromeDriverManager.installed:
ChromeDriverManager(*args, **kwargs).install() ChromeDriverManager(*args, **kwargs).install()
if not ChromeDriverManager.selenium_patched: if not ChromeDriverManager.selenium_patched:
ChromeDriverManager(*args, **kwargs).patch_selenium_webdriver() ChromeDriverManager(*args, **kwargs).patch_selenium_webdriver()
if not kwargs.get('executable_path'): if not kwargs.get("executable_path"):
kwargs['executable_path'] = './{}'.format(ChromeDriverManager(*args, **kwargs).executable_path) kwargs["executable_path"] = "./{}".format(
if not kwargs.get('options'): ChromeDriverManager(*args, **kwargs).executable_path
kwargs['options'] = ChromeOptions() )
if not kwargs.get("options"):
kwargs["options"] = ChromeOptions()
instance = object.__new__(_Chrome) instance = object.__new__(_Chrome)
instance.__init__(*args, **kwargs) instance.__init__(*args, **kwargs)
instance.execute_cdp_cmd( instance.execute_cdp_cmd(
@ -72,9 +72,7 @@ class Chrome:
) )
instance.execute_cdp_cmd( instance.execute_cdp_cmd(
"Network.setUserAgentOverride", "Network.setUserAgentOverride",
{ {"userAgent": original_user_agent_string.replace("Headless", ""),},
"userAgent": original_user_agent_string.replace("Headless", ""),
},
) )
logger.info(f"starting undetected_chromedriver.Chrome({args}, {kwargs})") logger.info(f"starting undetected_chromedriver.Chrome({args}, {kwargs})")
return instance return instance
@ -86,7 +84,7 @@ class ChromeOptions:
ChromeDriverManager(*args, **kwargs).install() ChromeDriverManager(*args, **kwargs).install()
if not ChromeDriverManager.selenium_patched: if not ChromeDriverManager.selenium_patched:
ChromeDriverManager(*args, **kwargs).patch_selenium_webdriver() ChromeDriverManager(*args, **kwargs).patch_selenium_webdriver()
instance = object.__new__(_ChromeOptions) instance = object.__new__(_ChromeOptions)
instance.__init__() instance.__init__()
instance.add_argument("start-maximized") instance.add_argument("start-maximized")
@ -104,30 +102,31 @@ class ChromeDriverManager(object):
DL_BASE = "https://chromedriver.storage.googleapis.com/" DL_BASE = "https://chromedriver.storage.googleapis.com/"
def __init__(self, executable_path=None, target_version=None, *args, **kwargs): def __init__(self, executable_path=None, target_version=None, *args, **kwargs):
_platform = sys.platform _platform = sys.platform
if TARGET_VERSION: # user override using global if TARGET_VERSION: # user override using global
self.target_version = TARGET_VERSION self.target_version = TARGET_VERSION
if target_version: if target_version:
self.target_version = target_version # user override self.target_version = target_version # user override
if not self.target_version: if not self.target_version:
# if target_version still not set, fetch the current major release version # if target_version still not set, fetch the current major release version
self.target_version = self.get_release_version_number().version[0] # only major version int self.target_version = self.get_release_version_number().version[
0
] # only major version int
self._base = base_ = "chromedriver{}" self._base = base_ = "chromedriver{}"
exe_name = self._base exe_name = self._base
if _platform in ('win32',): if _platform in ("win32",):
exe_name = base_.format(".exe") exe_name = base_.format(".exe")
if _platform in ('linux',): if _platform in ("linux",):
_platform+='64' _platform += "64"
exe_name = exe_name.format('') exe_name = exe_name.format("")
if _platform in ('darwin',): if _platform in ("darwin",):
_platform = 'mac64' _platform = "mac64"
exe_name = exe_name.format('') exe_name = exe_name.format("")
self.platform = _platform self.platform = _platform
self.executable_path = executable_path or exe_name self.executable_path = executable_path or exe_name
self._exe_name = exe_name self._exe_name = exe_name
@ -140,14 +139,12 @@ class ChromeDriverManager(object):
""" """
import selenium.webdriver.chrome.service import selenium.webdriver.chrome.service
import selenium.webdriver import selenium.webdriver
selenium.webdriver.Chrome = Chrome selenium.webdriver.Chrome = Chrome
selenium.webdriver.ChromeOptions = ChromeOptions selenium.webdriver.ChromeOptions = ChromeOptions
logger.warning( logger.warning("Selenium patched. Safe to import Chrome / ChromeOptions")
"Selenium patched. Safe to import Chrome / ChromeOptions"
)
self_.__class__.selenium_patched = True self_.__class__.selenium_patched = True
def install(self, patch_selenium=True): def install(self, patch_selenium=True):
""" """
Initialize the patch Initialize the patch
@ -168,7 +165,6 @@ class ChromeDriverManager(object):
if patch_selenium: if patch_selenium:
self.patch_selenium_webdriver() self.patch_selenium_webdriver()
def get_release_version_number(self): def get_release_version_number(self):
""" """
Gets the latest major version available, or the latest major version of self.target_version if set explicitly. Gets the latest major version available, or the latest major version of self.target_version if set explicitly.
@ -182,7 +178,6 @@ class ChromeDriverManager(object):
) )
return LooseVersion(urlopen(self.__class__.DL_BASE + path).read().decode()) return LooseVersion(urlopen(self.__class__.DL_BASE + path).read().decode())
def fetch_chromedriver(self): def fetch_chromedriver(self):
""" """
Downloads ChromeDriver from source and unpacks the executable Downloads ChromeDriver from source and unpacks the executable
@ -201,11 +196,10 @@ class ChromeDriverManager(object):
with zipfile.ZipFile(zip_name) as zf: with zipfile.ZipFile(zip_name) as zf:
zf.extract(self._exe_name) zf.extract(self._exe_name)
os.remove(zip_name) os.remove(zip_name)
if sys.platform != 'win32': if sys.platform != "win32":
os.chmod(self._exe_name, 0o755) os.chmod(self._exe_name, 0o755)
return self._exe_name return self._exe_name
def patch_binary(self): def patch_binary(self):
""" """
Patches the ChromeDriver binary Patches the ChromeDriver binary