Uruchamianie Selenium Webdriver z proxy w Pythonie

85

Próbuję uruchomić skrypt Selenium Webdriver w Pythonie, aby wykonać kilka podstawowych zadań. Mogę sprawić, by robot działał idealnie, gdy uruchamiam go przez interfejs Selenium IDE (tj. Po prostu zmuszając GUI do powtarzania moich działań). Jednak kiedy wyeksportuję kod jako skrypt Pythona i spróbuję wykonać go z wiersza poleceń, przeglądarka Firefox otworzy się, ale nigdy nie będzie mogła uzyskać dostępu do początkowego adresu URL (błąd jest zwracany do wiersza poleceń i program zatrzymuje się). Dzieje się tak niezależnie od tego, do której strony internetowej itp. Próbuję uzyskać dostęp.

Dołączyłem tutaj bardzo podstawowy kod do celów demonstracyjnych. Wydaje mi się, że sekcję proxy w kodzie nie umieściłem poprawnie, ponieważ zwracany błąd wydaje się być generowany przez serwer proxy.

Każda pomoc byłaby bardzo doceniona.

Poniższy kod ma po prostu otworzyć stronę www.google.ie i wyszukać słowo „selen”. Dla mnie otwiera pustą przeglądarkę Firefox i zatrzymuje się.

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()
user2479813
źródło

Odpowiedzi:

42

U mnie działa w ten sposób (podobnie do kodu @Amey i @ user4642224, ale trochę krócej):

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)
Mykhail Martsyniuk
źródło
2
to działa, dziękuję. dziwne, że dokumentacja mówi, że musisz użyć zdalnego sterownika.
Mans,
driver = webdriver.Firefox (allowed_capabilities =abilities) TypeError: __init __ () otrzymał nieoczekiwany argument z słowem kluczowym „required_capabilities” dlaczego?
Rimo
33

Co powiesz na coś takiego

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)

Więcej na ten temat przeczytasz tutaj .

Amey
źródło
Ta odpowiedź działała dobrze dla mnie. W przypadku, gdy ktoś inny próbuje to zrobić za pomocą Edge, webdriver.DesiredCapabilities.EDGE['proxy']nie ma to żadnego skutku, ponieważ Microsoft Edge obecnie nie ma ustawienia konfigurowania serwera proxy (aby używać Edge z proxy, musisz skonfigurować proxy w ustawieniach połączenia sieciowego Windows) .
Steve HHH
1
Pełen szczegółowy dokument można znaleźć na stronie: github.com/SeleniumHQ/selenium/wiki/…
LeckieNi
15

Moje rozwiązanie:

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)

Następnie wprowadź swój kod:

my_proxy(PROXY_HOST,PROXY_PORT)

Miałem problemy z tym kodem, ponieważ przekazywałem ciąg jako numer portu:

 PROXY_PORT="31280"

To jest ważne:

int("31280")

Musisz podać liczbę całkowitą zamiast ciągu, w przeciwnym razie Twój profil Firefoksa nie zostanie ustawiony na prawidłowy port, a połączenie przez serwer proxy nie będzie działać.

mrki
źródło
1
Port musi zostać przekonwertowany na int? To spowodowałoby, że przykład proxy Firefoksa na oficjalnej stronie byłby nieprawidłowy: seleniumhq.org/docs/04_webdriver_advanced.jsp W tym przykładzie PROXYHOST: PROXYPORT jest przekazywany jako ciąg.
Pyderman
@Pyderman, mylisz Proxy()klasę z FirefoxProfile()klasą. Korzystając z preferencji profilu, musisz osobno przekazywać IP i port oraz przesyłać portdo int(). W Proxy()klasie po prostu podajesz łańcuch zawierający "IP: PORT" i na pewno resztę pracy wykona za Ciebie.
m3nda
7

Spróbuj także skonfigurować serwer proxy sock5. Miałem ten sam problem i można go rozwiązać za pomocą proxy skarpet

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)

Następnie zadzwoń install_proxy ( ip , port ) ze swojego programu.

chowmean
źródło
jak zmodyfikowałbyś to, aby akceptować poświadczenia proxy?
nomaam
7

Proxy z weryfikacją. To jest zupełnie nowy skrypt Pythona w nawiązaniu do przykładowego skryptu Mykhail Martsyniuk.

# 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/")
Mario Uvera
źródło
6

Jeśli ktoś szuka rozwiązania, oto jak:

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/')
user4642224
źródło
4

Spróbuj, konfigurując 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")

Ten program został przetestowany zarówno w systemie Windows 8, jak i Mac OSX. Jeśli używasz Mac OSX i nie zaktualizowałeś selenu, możesz napotkać selenium.common.exceptions.WebDriverException. Jeśli tak, spróbuj ponownie po ulepszeniu selenu

pip install -U selenium
Rafayet Ullah
źródło
4

Powyższy wynik może być poprawny, ale nie działa z najnowszym webdriverem. Oto moje rozwiązanie powyższego pytania. Proste i słodkie


        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()

LUB

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

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

    driver = webdriver.Firefox(proxy=proxyDict)
Dugini Vijay
źródło
2

Odpowiedzi powyżej i na to pytanie albo nie działały dla mnie z Selenium 3.14 i Firefox 68.9 w systemie Linux, albo są niepotrzebnie złożone. Musiałem użyć konfiguracji WPAD, czasami za serwerem proxy (w sieci VPN), a czasami nie. Po lekkim przestudiowaniu kodu wymyśliłem:

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)

Inicjalizacja proxy ustawia proxyType na ProxyType.PAC (autokonfiguracja z adresu URL) jako efekt uboczny.

Działał również z funkcją automatycznego wykrywania przeglądarki Firefox, używając:

from selenium.webdriver.common.proxy import ProxyType

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

Ale nie sądzę, żeby to zadziałało zarówno z wewnętrznymi adresami URL (bez serwera proxy), jak iz zewnętrznymi (przez serwer proxy), tak jak robi to WPAD. Podobne ustawienia proxy powinny działać również w przypadku konfiguracji ręcznej. Możliwe ustawienia proxy można zobaczyć w kodzie tutaj .

Zauważ, że bezpośrednie przekazanie obiektu Proxy jako proxy=proxysterownika NIE działa - jest akceptowane, ale ignorowane (powinno być ostrzeżenie o wycofaniu, ale w moim przypadku myślę, że Behave go połyka).

Ron HD
źródło
0

Jak stwierdził @Dugini, niektóre wpisy konfiguracyjne zostały usunięte. Maksymalny:

webdriver.DesiredCapabilities.FIREFOX['proxy'] = {
    "httpProxy":PROXY,
    "ftpProxy":PROXY,
    "sslProxy":PROXY,
    "noProxy":[],
    "proxyType":"MANUAL"
 }
serv-inc
źródło
0

To zadziałało dla mnie i pozwoliło na użycie bezgłowej przeglądarki, wystarczy wywołać metodę przekazującą proxy.

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)
0x3l
źródło
-2

spróbuj uruchomić usługę Tor, dodaj następującą funkcję do swojego kodu.

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()
o.awajan
źródło
W tym poście brakuje informacji, funkcje connect_tor () i main () nie mają poprawnego wcięcia, a wywołanie connect_tor () nie zawiera obowiązkowego argumentu „port” w przykładzie. Którego portu Tor powinienem używać? Gdzie mogę uzyskać informacje o porcie Tora?
Karl
Sieć Tor (nawet jeśli dodaje dodatkową warstwę anonimowości) jest bardzo powolna.
Sceptic