From 2631da9c1093e3f32718ff2615195af700e8898b Mon Sep 17 00:00:00 2001 From: Alexandr Date: Wed, 10 Feb 2021 22:35:35 +0300 Subject: [PATCH] update --- example/example.py | 14 ++++-- example/selenium_helper.py | 44 +++++++++++++++--- ....4-fx.xpi => selenium_helper-0.0.6-fx.xpi} | Bin 28799 -> 29111 bytes 3 files changed, 48 insertions(+), 10 deletions(-) rename releases/{selenium_helper-0.0.4-fx.xpi => selenium_helper-0.0.6-fx.xpi} (58%) diff --git a/example/example.py b/example/example.py index 4fba584..b416bb5 100644 --- a/example/example.py +++ b/example/example.py @@ -1,5 +1,6 @@ import logging import os.path +import os import selenium.webdriver @@ -8,6 +9,11 @@ import selenium_helper def main(): logger = logging.getLogger(__name__) + + if "FIREFOX_PROXY" not in os.environ: + logger.error("Setup FIREFOX_PROXY in environment and try again!") + raise SystemExit(1) + profile = selenium.webdriver.FirefoxProfile() # отключаем предупреждение при открытии about:config profile.set_preference("browser.aboutConfig.showWarning", False) @@ -21,12 +27,14 @@ def main(): try: selenium_helper_extention = selenium_helper.SeleniumHelperExtension(driver) - selenium_helper_extention.install(os.path.abspath("releases/selenium_helper-0.0.4-fx.xpi")) - proxy = "http://username:password@host:port" + selenium_helper_extention.install(os.path.abspath("releases/selenium_helper-0.0.6-fx.xpi")) + # http://username:password@host:port + proxy = os.environ["FIREFOX_PROXY"] cookies = [ selenium_helper.Cookie(name="cookie", value="test", url="https://whoer.net") ] - selenium_helper_extention.begin_options().set_proxy(proxy).set_cookies(cookies).apply_options() + + selenium_helper_extention.begin_options().push(proxy, cookies, {}) driver.get("https://whoer.net/") input("Enter to exit...") diff --git a/example/selenium_helper.py b/example/selenium_helper.py index 8c0f0f4..4f5d780 100644 --- a/example/selenium_helper.py +++ b/example/selenium_helper.py @@ -9,7 +9,7 @@ import copy import json import urllib.parse from functools import lru_cache -from typing import List +from typing import List, Dict from selenium.common.exceptions import NoSuchElementException from selenium.webdriver import Firefox @@ -21,6 +21,7 @@ OPTION_PROXY_PORT = "proxy_port" OPTION_PROXY_USERNAME = "proxy_username" OPTION_PROXY_PASSWORD = "proxy_password" OPTION_PROXY_COOKIES = "proxy_cookies" +OPTION_HEADERS = "headers" class NoAddonException(Exception): @@ -142,18 +143,18 @@ class Cookie(dict): @path.deleter def path(self): del self["path"] - + @property def same_site(self): """A cookies.SameSiteStatus value that indicates the SameSite state of the cookie. If omitted, it defaults to 0, 'no_restriction'. https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies/SameSiteStatus""" return self.get("sameSite") - + @same_site.setter def same_site(self, value): self["sameSite"] = value - + @same_site.deleter def same_site(self): del self["sameSite"] @@ -226,7 +227,8 @@ class SeleniumHelperExtension: OPTION_PROXY_PORT: "port", OPTION_PROXY_USERNAME: "username", OPTION_PROXY_PASSWORD: "password", - OPTION_PROXY_COOKIES: "cookies" + OPTION_PROXY_COOKIES: "cookies", + OPTION_HEADERS: "headers" } def __init__(self, driver: Firefox, raise_for_about_config=True): @@ -277,8 +279,11 @@ class SeleniumHelperExtension: self._fill_option(OPTION_PROXY_TYPE, proxy.scheme) self._fill_option(OPTION_PROXY_HOST, proxy.hostname) self._fill_option(OPTION_PROXY_PORT, proxy.port) - self._fill_option(OPTION_PROXY_USERNAME, proxy.username) - self._fill_option(OPTION_PROXY_PASSWORD, proxy.password) + try: + self._fill_option(OPTION_PROXY_USERNAME, proxy.username) + self._fill_option(OPTION_PROXY_PASSWORD, proxy.password) + except TypeError: + pass return self def set_cookies(self, cookies: List[Cookie], default_url=None, ignore_errors=False): @@ -292,10 +297,35 @@ class SeleniumHelperExtension: self._fill_option(OPTION_PROXY_COOKIES, value) return self + def set_headers(self, headers: List[Dict[str, str]]): + """устанавливаем заголовки браузера, для всех запросов.""" + value = json.dumps(headers) + self._fill_option(OPTION_HEADERS, value) + return self + + def push(self, proxy, cookies, headers): + + if proxy: + proxy = urllib.parse.urlparse(proxy) + proxy = { + "type": proxy.scheme, + "host": proxy.hostname, + "port": proxy.port, + "username": proxy.username, + "password": proxy.password + } + + js = f"""saveOptionsEx({json.dumps(proxy)}, {json.dumps(cookies)}, {json.dumps(headers)});""" + self._driver.execute_script(js) + return self + def apply_options(self): """сохраняем изменения сделанные на странице настроек""" self._driver.find_element_by_id("submit").click() + def clear_cookies(self, cookies: List[Cookie], default_url=None, ignore_errors=False): + return self._clear_cookies(cookies, default_url, ignore_errors) + def _clear_cookies(self, cookies: List[Cookie], default_url=None, ignore_errors=False): clear_value = [] diff --git a/releases/selenium_helper-0.0.4-fx.xpi b/releases/selenium_helper-0.0.6-fx.xpi similarity index 58% rename from releases/selenium_helper-0.0.4-fx.xpi rename to releases/selenium_helper-0.0.6-fx.xpi index 5da9238c5760c669d6eebb8ab88d5531f48bd3b7..44c9d0eb2271561343671d4264e05ebd74214d51 100644 GIT binary patch delta 10612 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