셀레니움 윈도우용 크롬드라이버 자동설치, 프록시 적용버전

import subprocess
import xml.etree.ElementTree as elemTree
import urllib
import urllib.request
import zipfile, requests
import subprocess, re
class ChromeAutoinstaller:
    def __init__(self, proxyHost):
        self.proxyHost = proxyHost

    def get_chrome_version(self):
        process = subprocess.Popen(
            ['reg', 'query', 'HKEY_CURRENT_USER\\Software\\Google\\Chrome\\BLBeacon', '/v', 'version'],
            stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL
        )
        output = process.communicate()
        if output and output[0] and len(output[0]) > 0:
            version = output[0].decode('UTF-8').strip().split()[-1]
        else:
            process = subprocess.Popen(
                ['powershell', '-command', '$(Get-ItemProperty -Path Registry::HKEY_CURRENT_USER\\Software\\Google\\chrome\\BLBeacon).version'],
                stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE
            )
            version = process.communicate()[0].decode('UTF-8').strip()
        return version

    def get_platform_architecture(self):
        if sys.platform.startswith('linux') and sys.maxsize > 2 ** 32:
            platform = 'linux'
            architecture = '64'
        elif sys.platform == 'darwin':
            platform = 'mac'
            architecture = '64'
        elif sys.platform.startswith('win'):
            platform = 'win'
            architecture = '32'
        else:
            raise RuntimeError('Could not determine chromedriver download URL for this platform.')
        return platform, architecture

    def get_chromedriver_url(self, version, no_ssl=False):
        if no_ssl:
            base_url = 'http://chromedriver.storage.googleapis.com/'
        else:
            base_url = 'https://chromedriver.storage.googleapis.com/'
        platform, architecture = self.get_platform_architecture()
        return base_url + version + '/chromedriver_' + platform + architecture + '.zip'

    def get_matched_chromedriver_version(self, version, no_ssl=False):
        if no_ssl:
            doc = urllib.request.urlopen('http://chromedriver.storage.googleapis.com').read()
        else:
            doc = urllib.request.urlopen('https://chromedriver.storage.googleapis.com').read()
        root = elemTree.fromstring(doc)
        for k in root.iter('{http://doc.s3.amazonaws.com/2006-03-01}Key'):
            if k.text.find(self.get_major_version(version) + '.') == 0:
                return k.text.split('/')[0]
        return

    def get_major_version(self, version):
        return version.split('.')[0]

    def download_chromedriver(self, path=None, no_ssl=False):
        chrome_version = self.get_chrome_version()
        if not chrome_version:
            print('Chrome is not installed.')
            return
        chromedriver_version = self.get_matched_chromedriver_version(chrome_version, no_ssl)
        if not chromedriver_version:
            print('Can not find chromedriver for currently installed chrome version.')
            return
        major_version = self.get_major_version(chromedriver_version)

        if path:
            if not os.path.isdir(path):
                raise ValueError(f'Invalid path: {path}')
            chromedriver_dir = os.path.join(
                os.path.abspath(path),
                major_version
            )
        else:
            chromedriver_dir = os.path.join(
                os.path.abspath(os.path.dirname(__file__)),
                major_version
            )
        chromedriver_filename = 'chromedriver.exe'
        chromedriver_filepath = os.path.join(chromedriver_dir, chromedriver_filename)
        if not os.path.isfile(chromedriver_filepath) or \
                not self.check_version(chromedriver_filepath, chromedriver_version):
            print(f'Downloading chromedriver ({chromedriver_version})...')
            if not os.path.isdir(chromedriver_dir):
                os.makedirs(chromedriver_dir)
            url = self.get_chromedriver_url(version=chromedriver_version, no_ssl=no_ssl)
            try:

                session = requests.Session()

                session.proxies = {
                    'http': self.proxyHost,
                    'https': self.proxyHost,
                }
                with open('driver.zip', 'wb') as f:
                    f.write(session.get(url).content)
            except:
                raise RuntimeError(f'Failed to download chromedriver archive: {url}')

            driver_zip = zipfile.ZipFile(os.path.abspath('driver.zip'))
            driver_zip.extract(chromedriver_filename, chromedriver_dir)
            driver_zip.close()
        else:
            print('Chromedriver is already installed.')
        if not os.access(chromedriver_filepath, os.X_OK):
            os.chmod(chromedriver_filepath, 0o744)
        return chromedriver_filepath

    def check_version(self, binary, required_version):
        try:
            version = subprocess.check_output([binary, '-v'])
            version = re.match(r'.*?([\d.]+).*?', version.decode('utf-8'))[1]
            if version == required_version:
                return True
        except Exception:
            return False
        return False

autoinstall = ChromeAutoinstaller()
chrome_version = autoinstall.download_chromedriver("http://0.0.0.0:0")

5 thoughts on “셀레니움 윈도우용 크롬드라이버 자동설치, 프록시 적용버전”

Leave a Comment