Запуск Selenium Webdriver с прокси в Python

Я пытаюсь запустить скрипт Selenium Webdriver в Python, чтобы выполнить некоторые основные задачи. Я могу заставить робота функционировать идеально, когда он запускает его через интерфейс Selenium IDE (то есть: когда просто заставляет графический интерфейс повторять мои действия). Однако, когда я экспортирую код как скрипт Python и пытаюсь выполнить его из командной строки, браузер Firefox откроется, но не сможет получить доступ к начальному URL-адресу (в командной строке возвращается ошибка, и программа останавливается). Это происходит со мной независимо от того, к какому веб-сайту и т. Д. Я пытаюсь получить доступ.

Я включил здесь очень простой код для демонстрационных целей. Я не думаю, что я правильно включил секцию прокси-кода, так как возвращаемая ошибка создается прокси.

Любая помощь будет принята с благодарностью.

Приведенный ниже код просто предназначен для открытия www.google.ie и поиска по слову "селен". Для меня это открывает пустой браузер Firefox и останавливается.

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
import unittest, time, re
from selenium.webdriver.common.proxy import *

class Testrobot2(unittest.TestCase):
    def setUp(self):

        myProxy = "http://149.215.113.110:70"

        proxy = Proxy({
        'proxyType': ProxyType.MANUAL,
        'httpProxy': myProxy,
        'ftpProxy': myProxy,
        'sslProxy': myProxy,
        'noProxy':''})

        self.driver = webdriver.Firefox(proxy=proxy)
        self.driver.implicitly_wait(30)
        self.base_url = "https://www.google.ie/"
        self.verificationErrors = []
        self.accept_next_alert = True

    def test_robot2(self):
        driver = self.driver
        driver.get(self.base_url + "/#gs_rn=17&gs_ri=psy-ab&suggest=p&cp=6&gs_id=ix&xhr=t&q=selenium&es_nrs=true&pf=p&output=search&sclient=psy-ab&oq=seleni&gs_l=&pbx=1&bav=on.2,or.r_qf.&bvm=bv.47883778,d.ZGU&fp=7c0d9024de9ac6ab&biw=592&bih=665")
        driver.find_element_by_id("gbqfq").clear()
        driver.find_element_by_id("gbqfq").send_keys("selenium")

    def is_element_present(self, how, what):
        try: self.driver.find_element(by=how, value=what)
        except NoSuchElementException, e: return False
        return True

    def is_alert_present(self):
        try: self.driver.switch_to_alert()
        except NoAlertPresentException, e: return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert = self.driver.switch_to_alert()
            alert_text = alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally: self.accept_next_alert = True

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
    unittest.main()

18 ответов

У меня так работает (похоже на код @Amey и @user4642224, но немного короче):

from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy, ProxyType

prox = Proxy()
prox.proxy_type = ProxyType.MANUAL
prox.http_proxy = "ip_addr:port"
prox.socks_proxy = "ip_addr:port"
prox.ssl_proxy = "ip_addr:port"

capabilities = webdriver.DesiredCapabilities.CHROME
prox.add_to_capabilities(capabilities)

driver = webdriver.Chrome(desired_capabilities=capabilities)

Как насчет чего-то вроде этого

PROXY = "149.215.113.110:70"

webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
    "httpProxy":PROXY,
    "ftpProxy":PROXY,
    "sslProxy":PROXY,
    "noProxy":None,
    "proxyType":"MANUAL",
    "class":"org.openqa.selenium.Proxy",
    "autodetect":False
}

# you have to use remote, otherwise you'll have to code it yourself in python to 
driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.FIREFOX)

Вы можете прочитать больше об этом здесь.

Мое решение:

def my_proxy(PROXY_HOST,PROXY_PORT):
        fp = webdriver.FirefoxProfile()
        # Direct = 0, Manual = 1, PAC = 2, AUTODETECT = 4, SYSTEM = 5
        print PROXY_PORT
        print PROXY_HOST
        fp.set_preference("network.proxy.type", 1)
        fp.set_preference("network.proxy.http",PROXY_HOST)
        fp.set_preference("network.proxy.http_port",int(PROXY_PORT))
        fp.set_preference("general.useragent.override","whater_useragent")
        fp.update_preferences()
        return webdriver.Firefox(firefox_profile=fp)

Затем позвоните в свой код:

my_proxy(PROXY_HOST,PROXY_PORT)

У меня были проблемы с этим кодом, потому что я передавал строку в качестве порта #:

 PROXY_PORT="31280"

Это важно:

int("31280")

Вы должны передать целое число вместо строки, иначе ваш профиль Firefox не будет правильно настроен на порт, и соединение через прокси не будет работать.

Это довольно старый пост, однако для других он может принести пользу, предоставив ответ на сегодняшний день, и все же изначально автор был очень близок к рабочему решению.

Прежде всего, настройка ftpProxy в настоящее время больше не поддерживается и выдает ошибку.

      proxy = Proxy({
        'proxyType': ProxyType.MANUAL,
        'httpProxy': myProxy,
        'ftpProxy': myProxy, # this will throw an error
        'sslProxy': myProxy,
        'noProxy':''})

Далее, вместо установки прокси-свойства, вы должны использовать такие параметры Firefox, как

      proxy = Proxy({
    'proxyType': ProxyType.MANUAL,
    'httpProxy': myProxy,
    'sslProxy': myProxy,
    'noProxy': ''})

options = Options()
options.proxy = proxy
driver = webdriver.Firefox(options=options)

Кроме того, не определяйте схему при указании прокси, особенно если вы хотите использовать один и тот же прокси для нескольких протоколов.

      myProxy = "149.215.113.110:70"

Все вместе это выглядит так

      from selenium import webdriver
from selenium.webdriver.common.proxy import *
from selenium.webdriver.firefox.options import Options

myProxy = "149.215.113.110:70"
proxy = Proxy({
    'proxyType': ProxyType.MANUAL,
    'httpProxy': myProxy,
    'sslProxy': myProxy,
    'noProxy': ''})

options = Options()
options.proxy = proxy
driver = webdriver.Firefox(options=options)
driver.get("https://www.google.ie")

Если кто-то ищет решение, вот как:

from selenium import webdriver
PROXY = "YOUR_PROXY_ADDRESS_HERE"
webdriver.DesiredCapabilities.FIREFOX['proxy']={
    "httpProxy":PROXY,
    "ftpProxy":PROXY,
    "sslProxy":PROXY,
    "noProxy":None,
    "proxyType":"MANUAL",
    "autodetect":False
}
driver = webdriver.Firefox()
driver.get('http://www.whatsmyip.org/')

Прокси с проверкой. Это совершенно новый скрипт на Python по ссылке с примера скрипта Михаила Марцынюка.

# Load webdriver
from selenium import webdriver

# Load proxy option
from selenium.webdriver.common.proxy import Proxy, ProxyType

# Configure Proxy Option
prox = Proxy()
prox.proxy_type = ProxyType.MANUAL

# Proxy IP & Port
prox.http_proxy = “0.0.0.0:00000”
prox.socks_proxy = “0.0.0.0:00000”
prox.ssl_proxy = “0.0.0.0:00000”

# Configure capabilities 
capabilities = webdriver.DesiredCapabilities.CHROME
prox.add_to_capabilities(capabilities)

# Configure ChromeOptions
driver = webdriver.Chrome(executable_path='/usr/local/share chromedriver',desired_capabilities=capabilities)

# Verify proxy ip
driver.get("http://www.whatsmyip.org/")

Попробуйте настроить прокси sock5 тоже. Я столкнулся с той же проблемой, и она решается с помощью прокси socks

def install_proxy(PROXY_HOST,PROXY_PORT):
        fp = webdriver.FirefoxProfile()
        print PROXY_PORT
        print PROXY_HOST
        fp.set_preference("network.proxy.type", 1)
        fp.set_preference("network.proxy.http",PROXY_HOST)
        fp.set_preference("network.proxy.http_port",int(PROXY_PORT))
        fp.set_preference("network.proxy.https",PROXY_HOST)
        fp.set_preference("network.proxy.https_port",int(PROXY_PORT))
        fp.set_preference("network.proxy.ssl",PROXY_HOST)
        fp.set_preference("network.proxy.ssl_port",int(PROXY_PORT))  
        fp.set_preference("network.proxy.ftp",PROXY_HOST)
        fp.set_preference("network.proxy.ftp_port",int(PROXY_PORT))   
        fp.set_preference("network.proxy.socks",PROXY_HOST)
        fp.set_preference("network.proxy.socks_port",int(PROXY_PORT))   
        fp.set_preference("general.useragent.override","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/7046A194A")
        fp.update_preferences()
        return webdriver.Firefox(firefox_profile=fp)

Тогда позвони install_proxy ( ip , port ) из вашей программы.

Приведенный выше результат может быть правильным, но он не работает с последней версией веб-драйвера. Вот мое решение для вышеуказанного вопроса. Простой и сладкий


        http_proxy  = "ip_addr:port"
        https_proxy = "ip_addr:port"

        webdriver.DesiredCapabilities.FIREFOX['proxy']={
            "httpProxy":http_proxy,
            "sslProxy":https_proxy,
            "proxyType":"MANUAL"
        }

        driver = webdriver.Firefox()

ИЛИ ЖЕ

    http_proxy  = "http://ip:port"
    https_proxy = "https://ip:port"

    proxyDict = {
                    "http"  : http_proxy,
                    "https" : https_proxy,
                }

    driver = webdriver.Firefox(proxy=proxyDict)

Это помогает мне в сентябре 2022 года - прокси для селена с авторизацией пользователя + пароль

      import os
import zipfile

from selenium import webdriver

PROXY_HOST = '192.168.3.2'  # rotating proxy or host
PROXY_PORT = 8080 # port
PROXY_USER = 'proxy-user' # username
PROXY_PASS = 'proxy-password' # password

manifest_json = """
{
    "version": "1.0.0",
    "manifest_version": 2,
    "name": "Chrome Proxy",
    "permissions": [
        "proxy",
        "tabs",
        "unlimitedStorage",
        "storage",
        "<all_urls>",
        "webRequest",
        "webRequestBlocking"
    ],
    "background": {
        "scripts": ["background.js"]
    },
    "minimum_chrome_version":"22.0.0"
}
"""

background_js = """
var config = {
        mode: "fixed_servers",
        rules: {
        singleProxy: {
            scheme: "http",
            host: "%s",
            port: parseInt(%s)
        },
        bypassList: ["localhost"]
        }
    };
chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});
function callbackFn(details) {
    return {
        authCredentials: {
            username: "%s",
            password: "%s"
        }
    };
}
chrome.webRequest.onAuthRequired.addListener(
            callbackFn,
            {urls: ["<all_urls>"]},
            ['blocking']
);
""" % (PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS)

def get_chromedriver(use_proxy=False, user_agent=None):
    path = os.path.dirname(os.path.abspath(__file__))
    chrome_options = webdriver.ChromeOptions()
    if use_proxy:
        pluginfile = 'proxy_auth_plugin.zip'

        with zipfile.ZipFile(pluginfile, 'w') as zp:
            zp.writestr("manifest.json", manifest_json)
            zp.writestr("background.js", background_js)
        chrome_options.add_extension(pluginfile)
    if user_agent:
        chrome_options.add_argument('--user-agent=%s' % user_agent)
    driver = webdriver.Chrome(
        os.path.join(path, 'chromedriver'),
        chrome_options=chrome_options)
    return driver

def main():
    driver = get_chromedriver(use_proxy=True)
    driver.get('https://ifconfig.me/)

if __name__ == '__main__':
    main()

ссылка на источник

Попробуйте, настроив FirefoxProfile

from selenium import webdriver
import time


"Define Both ProxyHost and ProxyPort as String"
ProxyHost = "54.84.95.51" 
ProxyPort = "8083"



def ChangeProxy(ProxyHost ,ProxyPort):
    "Define Firefox Profile with you ProxyHost and ProxyPort"
    profile = webdriver.FirefoxProfile()
    profile.set_preference("network.proxy.type", 1)
    profile.set_preference("network.proxy.http", ProxyHost )
    profile.set_preference("network.proxy.http_port", int(ProxyPort))
    profile.update_preferences()
    return webdriver.Firefox(firefox_profile=profile)


def FixProxy():
    ""Reset Firefox Profile""
    profile = webdriver.FirefoxProfile()
    profile.set_preference("network.proxy.type", 0)
    return webdriver.Firefox(firefox_profile=profile)


driver = ChangeProxy(ProxyHost ,ProxyPort)
driver.get("http://whatismyipaddress.com")

time.sleep(5)

driver = FixProxy()
driver.get("http://whatismyipaddress.com")

Эта программа протестирована как на Windows 8, так и на Mac OSX. Если вы используете Mac OSX и не обновляете селен, вы можете столкнуться с selenium.common.exceptions.WebDriverException, Если это так, то попробуйте еще раз после обновления вашего селена

pip install -U selenium

Удивлен отсутствием примеров использования аутентифицированных прокси.

Решение от октября 2022 г. для аутентифицированных прокси (Firefox и Chrome):

      from selenium import webdriver

PROXY_HOST = "0.0.0.0";
PROXY_PORT = "0000"
PROXY_USERNAME = "user"
PROXY_PASS = "pass"

# If you're using Firefox
profile = webdriver.FirefoxProfile()
profile.set_preference("network.proxy.type", 1)
profile.set_preference("network.proxy.http",PROXY_HOST) 
profile.set_preference("network.proxy.http_port", PROXY_PORT) 
fp.set_preference('network.proxy.no_proxies_on', 'localhost, 127.0.0.1')
credentials = '%s:%s' % (PROXY_USERNAME, PROXY_PASS)
credentials = b64encode(credentials.encode('ascii')).decode('utf-8')
fp.set_preference('extensions.closeproxyauth.authtoken', credentials)
driver = webdriver.Firefox(firefox_profile=profile)

# If you're using Chrome
chrome_options = WebDriver.ChromeOptions()
options.add_argument('--proxy-server=http://%s:%s@%s:%s' % (PROXY_HOST, PROXY_PORT, PROXY_USERNAME, PROXY_PASS))
driver = webdriver.Chrome(executable_path='chromedriver.exe', chrome_options=chrome_options)

# Proxied request
driver.get("https://www.google.com")

Некоторые полезные сетевые прокси-ресурсы с быстрой интеграцией Selenium

  1. Яркие данные
  2. СОАКС
  3. NetNut

Ответы выше и на этот вопрос либо не помогли мне с Selenium 3.14 и Firefox 68.9 в Linux, либо являются излишне сложными. Мне нужно было использовать конфигурацию WPAD, иногда за прокси (в VPN), а иногда нет. Немного изучив код, я пришел к следующему:

from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

proxy = Proxy({'proxyAutoconfigUrl': 'http://wpad/wpad.dat'})
profile = FirefoxProfile()
profile.set_proxy(proxy)
driver = webdriver.Firefox(firefox_profile=profile)

Инициализация Proxy устанавливает proxyType на ProxyType.PAC (автоконфигурация из URL-адреса) в качестве побочного эффекта.

Он также работал с автоопределением Firefox, используя:

from selenium.webdriver.common.proxy import ProxyType

proxy = Proxy({'proxyType': ProxyType.AUTODETECT})

Но я не думаю, что это будет работать как с внутренними URL (не проксируемыми), так и внешними (проксированными), как это делает WPAD. Подобные настройки прокси должны работать и для ручной настройки. Возможные настройки прокси можно увидеть в коде здесь.

Обратите внимание, что прямая передача объекта Proxy как proxy=proxy к драйверу НЕ работает - он принят, но игнорируется (должно быть предупреждение об устаревании, но в моем случае я думаю, что Behave проглатывает его).

Это сработало для меня и позволило использовать браузер без головы, вам просто нужно вызвать метод, передающий ваш прокси.

def setProxy(proxy):
        options = Options()
        options.headless = True
        #options.add_argument("--window-size=1920,1200")
        options.add_argument("--disable-dev-shm-usage")
        options.add_argument("--no-sandbox")
        prox = Proxy()
        prox.proxy_type = ProxyType.MANUAL
        prox.http_proxy = proxy
        prox.ssl_proxy = proxy
        capabilities = webdriver.DesiredCapabilities.CHROME
        prox.add_to_capabilities(capabilities)
        return webdriver.Chrome(desired_capabilities=capabilities, options=options, executable_path=DRIVER_PATH)

Как утверждает @Dugini, некоторые записи конфигурации были удалены. Максимальный:

webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
    "httpProxy":PROXY,
    "ftpProxy":PROXY,
    "sslProxy":PROXY,
    "noProxy":[],
    "proxyType":"MANUAL"
 }

При использовании API-интерфейсов парсинга данные из любого онлайн-источника довольно просты. Вы можете попробовать использовать scraper API, чтобы очистить информацию с веб-страниц, и он автоматически анализирует веб-данные. API также может быть интегрирован в ваш исходный код. Помимо использования API для очистки данных, вы можете попробовать нижеупомянутый исходный код в красивом супе для очистки данных с помощью селекторов CSS. Прежде чем пробовать этот код, обратите внимание, что метод select() можно использовать для поиска множества элементов. Наряду с этим, select_one() будет использоваться для поиска по одному элементу.

Исходный код:

      from selenium import webdriver
from selenium.webdriver.chrome.options import Options
PROXY = "177.46.141.143:59393" #your proxy  (ip address: port no)
chrome_options = WebDriverWait.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % PROXY)
chrome = webdriver.Chrome(chrome_options=chrome_options)
chrome.get("https://www.ipchicken.com/")

Решение от января 2023 г. с аутентификацией и SSL для Firefox

      from selenium import webdriver

PROXY_HOST = "ip"
PROXY_PORT = "port"
PROXY_USERNAME = "username"
PROXY_PASS = "password"

profile = webdriver.FirefoxProfile()
profile.set_preference("network.proxy.type", 1)
profile.set_preference('network.proxy.ssl_port', int(PROXY_PORT))
profile.set_preference('network.proxy.ssl', PROXY_HOST)
profile.set_preference("network.proxy.http", PROXY_HOST)
profile.set_preference("network.proxy.http_port", int(PROXY_PORT))
profile.set_preference("network.proxy.no_proxies_on", 'localhost, 127.0.0.1')
profile.set_preference("network.proxy.socks_username", PROXY_USERNAME)
profile.set_preference("network.proxy.socks_password", PROXY_PASS)
profile.update_preferences()

driver = webdriver.Firefox(firefox_profile=profile)

driver.get("https://2ip.ru")

Также есть вероятность, что вам может понадобиться заблокировать свой IP-адрес в настройках учетной записи прокси-провайдера. В противном случае вам будет предложено ввести учетные данные при загрузке страницы.

Поддержка аутентифицированного прокси. сентябрь 2023 г.

Я знаю два способа поддержки аутентифицированных прокси в селене. Я покажу оба.

Способ 1: селеновая проволока

Если вы хотите загрузить другую библиотеку, расширяющую базовую библиотеку селена. Поддержка аутентифицированного прокси-сервера может быть добавлена ​​через библиотеку selenium-wire .

Следует отметить, что использование этого метода приведет к тому, что браузер сообщит, что соединение «небезопасно», поскольку seleniumwire использует собственный корневой сертификат для перехвата запросов. Можно загрузить сертификат seleniumwire и предотвратить это, однако в этом примере я не буду этого делать и вместо этого предпочитаю игнорировать незащищенное предупреждение. Если это не идеальный вариант и вы не хотите загружать корневой сертификат, см. метод 2. Дополнительную информацию об обработке сертификатов Seleniumwire см . здесь .

В приведенном ниже коде представлена ​​реализация с использованием библиотеки selenium-wire .

      from seleniumwire import webdriver

proxy_host = "your_host"
proxy_port = 8888
proxy_user = "your_username"
proxy_pass = "your_password"

seleniumwire_options = {
    "proxy":{
        "http":f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}",
        "verify_ssl":False,
    }
}

chrome_options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors') #ignore the 'unsecured' warning caused by seleniumwires root certificate (if certificate is not installed)

driver = webdriver.Chrome(
    options=chrome_options,
    seleniumwire_options=seleniumwire_options,
)

driver.get('http://httpbin.org/ip')
input()
driver.quit()

Способ 2: расширение Chrome

Другой способ использования прокси в селене — использование расширения Chrome, которое автоматически загружает прокси в Chrome и аутентифицирует его с помощью относительных учетных данных при запросе.

Я буду использовать расширение Chrome, аналогичное предложенному @Jackssn, но переписанное для поддержки манифеста v3; поскольку версия 2 устарела в 2023 году.

См. код ниже:

      from selenium import webdriver
from pathlib import Path
import shutil

## js strings to be written to file when creating chrome extension

ext_json_manifest = """{
    "manifest_version": 3,
    "name": "Proxy Loader",
    "version": "1.0.0",
    "background":{
        "service_worker":"service-worker.js"
    },
    "permissions":[
        "proxy",
        "webRequest",
        "webRequestAuthProvider"
    ],
    "host_permissions":[
        "<all_urls>"
    ],
    "minimum_chrome_version": "108"
}"""

ext_js_serviceworker = """host = "%s"
port = %s
username = "%s"
password = "%s"


var config = {
    mode:"fixed_servers",
    rules:{
        singleProxy:{
            host:host,
            port:port,
            scheme:"http",
        },
        bypassList:["localhost"] //wont use a proxy for these sites
    }
}

chrome.proxy.settings.set(
    {value:config,scope:"regular"},
    function(){}
)

// supply proxy auth credentials when prompted.
chrome.webRequest.onAuthRequired.addListener(
    function(details) { //
        return {
            authCredentials:{
                username:username,
                password:password
            }
        }
    },
    {
        urls:["<all_urls>"] //which urls to provide credentials for
    },
    ["blocking"] //block the request until auth details have been supplied
)"""

## your proxy details
proxy_host = "your_host"
proxy_port = 8888
proxy_user = "your_username"
proxy_pass = "your_password"

## create extension
ext_path = "./extension/"
Path(ext_path).mkdir(parents=True,exist_ok=True)

with open(str(Path(ext_path).joinpath("manifest.json")),"w+") as f:
    f.write(ext_json_manifest)
    f.close()

with open(str(Path(ext_path).joinpath("service-worker.js")),"w+") as f:
    f.write(ext_js_serviceworker % (proxy_host,proxy_port,proxy_user,proxy_pass))
    f.close()

## configure and create driver
options = webdriver.ChromeOptions()
options.add_argument(f"--load-extension={str(Path(ext_path).absolute())}")

driver = webdriver.Chrome(
    options=options
)

## delete extension once loaded.
shutil.rmtree(ext_path)

## check selenium is using the proxy.
driver.get('http://httpbin.org/ip')
input()
driver.quit()

Попробуйте запустить сервис tor, добавьте следующую функцию в ваш код.

def connect_tor (port):

socks.set_default_proxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', port, True)
socket.socket = socks.socksocket

def main ():

connect_tor()
driver = webdriver.Firefox()
Другие вопросы по тегам