Запуск 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
Ответы выше и на этот вопрос либо не помогли мне с 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()