Как установить прокси с аутентификацией в Селен Chromeriver Python?
Я создаю сценарий, который сканирует один веб-сайт для сбора некоторых данных, но проблема в том, что они заблокировали меня после слишком большого количества запросов, но с помощью прокси я могу отправить больше запросов, чем в настоящее время. Я интегрировал прокси с хромированной опцией --proxy-server
options.add_argument('--proxy-server={}'.format('http://ip:port'))
но я использую платный прокси, поэтому он требует аутентификации и, как показано на скриншоте ниже, он выдает окно предупреждения для имени пользователя и пароля
Затем я попытался использовать его с именем пользователя и паролем
options.add_argument('--proxy-server={}'.format('http://username:password@ip:port'))
Но это также не похоже на работу. Я искал решение и нашел ниже решение, и я использовал его с автоматической аутентификацией прокси расширения Chrome и без расширения Chrome
proxy = {'address': settings.PROXY,
'username': settings.PROXY_USER,
'password': settings.PROXY_PASSWORD}
capabilities = dict(DesiredCapabilities.CHROME)
capabilities['proxy'] = {'proxyType': 'MANUAL',
'httpProxy': proxy['address'],
'ftpProxy': proxy['address'],
'sslProxy': proxy['address'],
'noProxy': '',
'class': "org.openqa.selenium.Proxy",
'autodetect': False,
'socksUsername': proxy['username'],
'socksPassword': proxy['password']}
options.add_extension(os.path.join(settings.DIR, "extension_2_0.crx")) # proxy auth extension
но ни один из вышеперечисленных не работал должным образом, кажется, работает, потому что после вышеприведенного кода предупреждение аутентификации прокси исчезло, и когда я проверил свой IP, найдя мой IP, и подтвердил, что он не работает.
Пожалуйста, кто-нибудь, кто может помочь мне аутентифицировать прокси-сервер на chromedriver.
12 ответов
Проверка подлинности Selenium Chrome Proxy
Настройка прокси для chromedriver с помощью Selenium с использованием Python
Если вам нужно использовать прокси с Python и библиотеку Selenium с chromedriver, вы обычно используете следующий код (без имени пользователя и пароля:
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=%s' % hostname + ":" + port)
driver = webdriver.Chrome(chrome_options=chrome_options)
Работает нормально, если прокси не требует аутентификации. если прокси-сервер требует, чтобы вы вошли в систему с именем пользователя и паролем, он не будет работать. В этом случае вам придется использовать более хитрое решение, которое объясняется ниже. Кстати, если вы заносите в белый список IP-адрес вашего сервера от прокси-провайдера или сервера, он не должен запрашивать учетные данные прокси.
Проверка подлинности прокси HTTP с помощью Chromedriver в Selenium
Для настройки прокси-аутентификации мы сгенерируем специальный файл и динамически загрузим его в chromedriver, используя следующий код ниже. Этот код настраивает селен с помощью chromedriver для использования HTTP-прокси, который требует аутентификации с парой пользователь / пароль.
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://www.google.com/search?q=my+ip+address')
driver.get('https://httpbin.org/ip')
if __name__ == '__main__':
main()
Функция get_chromedriver возвращает настроенный селеновый веб-драйвер, который вы можете использовать в своем приложении. Этот код протестирован и работает просто отлично.
Используйте селеновую проволоку.
Пример кода из документации:
options = {
'proxy': {
'http': 'socks5://user:pass@192.168.10.100:8888',
'https': 'socks5://user:pass@192.168.10.100:8888',
'no_proxy': 'localhost,127.0.0.1'
}
}
driver = webdriver.Chrome(seleniumwire_options=options)
Вот быстрое, креативное решение, которое не требует изменения параметров селена или загрузки файла в chromedriver. Он использует pyautogui (может использовать любой пакет python, имитирующий нажатие клавиш) для ввода деталей аутентификации прокси. Он также использует многопоточность для учета всплывающего окна проверки подлинности Chrome, которое в противном случае приостановило бы выполнение сценария.
import time
from threading import Thread
import pyautogui
from selenium.webdriver.chrome.options import Options
from selenium import webdriver
hostname = "HOST_NAME"
port = "PORT"
proxy_username = "USERNAME"
proxy_password = "PASSWORD"
chrome_options = Options()
chrome_options.add_argument('--proxy-server={}'.format(hostname + ":" + port))
driver = webdriver.Chrome(options=chrome_options)
def enter_proxy_auth(proxy_username, proxy_password):
time.sleep(1)
pyautogui.typewrite(proxy_username)
pyautogui.press('tab')
pyautogui.typewrite(proxy_password)
pyautogui.press('enter')
def open_a_page(driver, url):
driver.get(url)
Thread(target=open_a_page, args=(driver, "http://www.example.com/")).start()
Thread(target=enter_proxy_auth, args=(proxy_username, proxy_password)).start()
ПРИМЕЧАНИЕ. Для любого серьезного проекта или набора тестов я бы рекомендовал выбрать более надежное решение. Однако, если вы только экспериментируете и вам требуется быстрое и эффективное решение, это вариант.
Я искал тот же ответ, но только для кода Java, так что вот мой вариант кода @itsmnthn Python.
Не забудьте изменить поля String класса MainTest на свой IP, порт, логин, пароль и путь chromeDriver.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class MainTest {
private static final String PROXY_HOST = "127.0.0.1";
private static final String PROXY_PORT = "8080";
private static final String PROXY_USER = "login";
private static final String PROXY_PASS = "password";
private static final String CHROMEDRIVER_PATH = "chromeDriverPath";
private static final String PROXY_OPTION_TEMPLATE = "--proxy-server=http://%s";
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.chrome.driver", CHROMEDRIVER_PATH);
ChromeOptions options = new ChromeOptions();
String manifest_json = "{\n" +
" \"version\": \"1.0.0\",\n" +
" \"manifest_version\": 2,\n" +
" \"name\": \"Chrome Proxy\",\n" +
" \"permissions\": [\n" +
" \"proxy\",\n" +
" \"tabs\",\n" +
" \"unlimitedStorage\",\n" +
" \"storage\",\n" +
" \"<all_urls>\",\n" +
" \"webRequest\",\n" +
" \"webRequestBlocking\"\n" +
" ],\n" +
" \"background\": {\n" +
" \"scripts\": [\"background.js\"]\n" +
" },\n" +
" \"minimum_chrome_version\":\"22.0.0\"\n" +
"}";
String background_js = String.format("var config = {\n" +
" mode: \"fixed_servers\",\n" +
" rules: {\n" +
" singleProxy: {\n" +
" scheme: \"http\",\n" +
" host: \"%s\",\n" +
" port: parseInt(%s)\n" +
" },\n" +
" bypassList: [\"localhost\"]\n" +
" }\n" +
"};\n" +
"\n" +
"chrome.proxy.settings.set({value: config, scope: \"regular\"}, function() {});\n" +
"\n" +
"function callbackFn(details) {\n" +
"return {\n" +
"authCredentials: {\n" +
"username: \"%s\",\n" +
"password: \"%s\"\n" +
"}\n" +
"};\n" +
"}\n" +
"\n" +
"chrome.webRequest.onAuthRequired.addListener(\n" +
"callbackFn,\n" +
"{urls: [\"<all_urls>\"]},\n" +
"['blocking']\n" +
");", PROXY_HOST, PROXY_PORT, PROXY_USER, PROXY_PASS);
FileOutputStream fos = new FileOutputStream("proxy_auth_plugin.zip");
ZipOutputStream zipOS = new ZipOutputStream(fos);
createFile("manifest.json", manifest_json);
createFile("background.js", background_js);
File file = new File("proxy_auth_plugin.zip");
writeToZipFile("manifest.json", zipOS);
writeToZipFile("background.js", zipOS);
zipOS.close();
fos.close();
options.addExtensions(file);
WebDriver driver = new ChromeDriver(options);
try {
driver.get("https://2ip.ru");
} finally {
driver.close();
}
}
public static void writeToZipFile(String path, ZipOutputStream zipStream) throws FileNotFoundException, IOException {
System.out.println("Writing file : '" + path + "' to zip file");
File aFile = new File(path);
FileInputStream fis = new FileInputStream(aFile);
ZipEntry zipEntry = new ZipEntry(path);
zipStream.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipStream.write(bytes, 0, length);
}
zipStream.closeEntry();
fis.close();
}
public static void createFile(String filename, String text) throws FileNotFoundException {
try (PrintWriter out = new PrintWriter(filename)) {
out.println(text);
}
}
}
После нескольких часов копания с той же проблемой, что и у вас, я наткнулся на этот веб-сайт https://botproxy.net/docs/how-to/setting-chromedriver-proxy-auth-with-selenium-using-python/. Я проверил это и отлично сработал.
import os
import zipfile
from selenium import webdriver
PROXY_HOST = 'x.botproxy.net' # rotating proxy
PROXY_PORT = 8080
PROXY_USER = 'proxy-user'
PROXY_PASS = 'proxy-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://www.google.com/search?q=my+ip+address')
driver.get('https://httpbin.org/ip')
if __name__ == '__main__':
main()
Поскольку не представляется возможным напрямую настроить Chromedriver для использования прокси-сервера, требующего аутентификации, вы можете использовать локальный нисходящий прокси-сервер, который не требует аутентификации. Затем этот локальный прокси-сервер отправляет все запросы на ваш «настоящий» прокси-сервер, который вы хотели использовать в первую очередь, с необходимой аутентификацией.
Для этого я использовал tinyproxy . Вы можете добавить следующую строку в конфигурацию tinyproxy (tinyproxy.conf):
upstream http user:pass@host:port
Обязательно замените пользователя, пароль, хост и порт значениями прокси-сервера, который вы хотите использовать.
Затем вы можете настроить свой Chromedriver для использования tinyproxy, как уже описано в предыдущих ответах. Tinyprox по умолчанию работает на порту 8888, поэтому вы можете связаться с ним по адресу 127.0.0.1:8888. Как уже упоминалось в этом ответе , довольно просто использовать прокси без аутентификации:
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--proxy-server=127.0.0.1:8888')
driver = webdriver.Chrome(chrome_options=chrome_options)
У меня была та же проблема - и разве нельзя объединить функцию selenium-wire с функцией headless из опций - например, для меня этот код работал - что-то не так?
from seleniumwire import webdriver
from selenium.webdriver.chrome.options import Options
import os, sys, time
from dotenv import load_dotenv, find_dotenv
path = os.path.abspath (os.path.dirname (sys.argv[0]))
cd = '/chromedriver.exe'
load_dotenv(find_dotenv())
PROXY_CHEAP_USER = os.environ.get("PROXY_CHEAP_USER")
PROXY_CHEAP_PW= os.environ.get("PROXY_CHEAP_PW")
PROXY_HOST = 'proxyhost.com' # rotating proxy or host
PROXY_PORT = port # port
PROXY_USER = PROXY_CHEAP_USER # username
PROXY_PASS = PROXY_CHEAP_PW # password
options = Options()
options.add_argument('--headless')
options.add_argument("--window-size=1920x1080")
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
options_seleniumWire = {
'proxy': {
'https': f'https://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}',
}
}
driver = webdriver.Chrome (path + cd, options=options, seleniumwire_options=options_seleniumWire)
driver.get("https://ifconfig.co/")
Думаю, это решение тоже работает в безголовом режиме.
Есть более простой способ, как сделать аутентификацию на прокси с помощью селена! Не знаю с какой версии работает, но в selenium-api-4.5.3 для java есть интерфейсHasAuthentication
. Вы можете использоватьregister
метод после инициализации драйвера для установки пользователя и пароля для всего браузера.
Это сработало для меня с хромом:
((ChromiumDriver) driver).register(() -> new UsernameAndPassword("USER", "PASS"));
и установите прокси в настройках
ChromeOptions options = new ChromeOptions();
options.setCapability("proxy", initProxy());
new ChromeDriver(options);
у меня тоже работает в безголовом режиме.
Вот манифест версии 3, сопровождающий последние версии решения Chrome и @itsmnthn.
{
"version": "1.0.0",
"manifest_version": 3,
"name": "Chrome Proxy",
"permissions": [
"proxy",
"tabs",
"unlimitedStorage",
"storage",
"webRequest",
"webRequestAuthProvider"
],
"host_permissions": [
"<all_urls>"
],
"background": {
"service_worker": "background.js"
},
"minimum_chrome_version":"22.0.0"
}
И класс С#, который решает эту проблему (опять же, на основе решения @itsmnthn)
public class ProxiedChromeClient : IDisposable
{
private const string MANIFEST_JSON = @"
{
""version"": ""1.0.0"",
""manifest_version"": 3,
""name"": ""Chrome Proxy"",
""permissions"": [
""proxy"",
""tabs"",
""unlimitedStorage"",
""storage"",
""webRequest"",
""webRequestAuthProvider""
],
""host_permissions"": [
""<all_urls>""
],
""background"": {
""service_worker"": ""background.js""
},
""minimum_chrome_version"":""22.0.0""
}";
private const string BACKGROUND_JS = @"
var config = {{
mode: ""fixed_servers"",
rules: {{
singleProxy: {{
scheme: ""{0}"",
host: ""{1}"",
port: parseInt({2})
}},
bypassList: [""localhost""]
}}
}};
chrome.proxy.settings.set({{value: config, scope: ""regular""}}, function() {{}});
function callbackFn(details) {{
return {{
authCredentials: {{
username: ""{3}"",
password: ""{4}""
}}
}};
}}
chrome.webRequest.onAuthRequired.addListener(
callbackFn,
{{urls: [""<all_urls>""]}},
['blocking']
);";
protected ProxiedChromeClient(ProxyInfo proxy = null)
{
var options = new ChromeOptions();
if (proxy != null)
{
extensionPath = CreateProxyExtension(proxy);
options.AddExtension(extensionPath);
}
chromeDriverInstance = new ChromeDriver(options);
}
protected readonly ChromeDriver chromeDriverInstance;
private readonly object @lock = new();
private readonly string extensionPath;
private static string CreateProxyExtension(ProxyInfo proxy)
{
// per https://stackoverflow.com/a/55582859/307584
var tempFile = Path.GetTempFileName();
using var z = new ZipArchive(new FileStream(tempFile, FileMode.Create), ZipArchiveMode.Create);
var entry = z.CreateEntry("manifest.json");
using (var writer = new StreamWriter(entry.Open()))
{
writer.Write(MANIFEST_JSON);
}
entry = z.CreateEntry("background.js");
var url = new Uri(proxy.Url);
using (var writer = new StreamWriter(entry.Open()))
{
writer.Write(BACKGROUND_JS, url.Scheme, url.Host, url.Port, proxy.User, proxy.Password);
}
return tempFile;
}
public void Dispose()
{
lock (@lock)
{
chromeDriverInstance.Quit();
if (extensionPath != null)
{
File.Delete(extensionPath);
}
}
}
}
Попутно в обновлениях решение, использующее расширение, не работает (по крайней мере, windows), в то время как mac и linux работают. Думаю это был chromedriver v2.44 последняя рабочая версия с расширениями
Мы создали общедоступное решение с открытым исходным кодом для решения именно этого случая, объединив эти замечательные ответы в этой теме и некоторые другие ответы о том, как правильно включить его в Chrome. Начиная с версии 114, в манифест.json были внесены некоторые существенные изменения. Пакет pypi устраняет все трудности, связанные с аутентификацией прокси-серверов в Selenium. Мы планируем поддерживать его, поскольку в значительной степени полагаемся на него для корпоративных приложений.
Просто беги
pip install selenium-authenticated-proxy
Вот как вы можете настроить его с помощью веб-драйвера:
from selenium import webdriver
from selenium_authenticated_proxy import SeleniumAuthenticatedProxy
# Initialize Chrome options
chrome_options = webdriver.ChromeOptions()
# Initialize SeleniumAuthenticatedProxy
proxy_helper = SeleniumAuthenticatedProxy(proxy_url="http://username:password@proxy-server.com")
# Enrich Chrome options with proxy authentication
proxy_helper.enrich_chrome_options(chrome_options)
# Start WebDriver with enriched options
driver = webdriver.Chrome(chrome_options=chrome_options)
# Your automation or scraping code here
Вы можете указать собственную папку для временного хранения созданных расширений Chrome.
proxy_helper = SeleniumAuthenticatedProxy(proxy_url="http://username:password@proxy-server.com", tmp_folder="/path/to/tmp/folder")
Есть несколько обходных путей для этой проблемы, но в настоящее время невозможно разрешить диалоговое окно аутентификации в Selenium. Смотрите этот выпуск:
В настоящее время нет способа обрабатывать запросы HTTP-аутентификации при переходе на страницу, работает только предварительная аутентификация с именем пользователя/паролем в URL-адресе (и, по-видимому, не без обходных путей в некоторых браузерах, таких как IE).