существует«Один навык в день: как правильно удалить значение Window.navigator.webdriver в Selenium»В этой статье мы рассказали об удалении Chrome из браузеров с запуском Selenium в то время.window.navigator.webdriver
Методы.
Позже, с течением времени, Chrome обновил версию, что сделало метод на тот момент неэффективным. Как показано ниже:
Как нам правильно скрыть этот параметр для последней версии Chrome?
В той статье я ругал способ прятать уши и красть колокольчик:
Откройте веб-страницу и скройте ее, выполнив следующую инструкцию JavaScript.window.navigator.webdriver
Значение:
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
Я ругал этот метод как воровство звонка, потому что они запускают этот код JavaScript после загрузки веб-страницы, но в это время собственная js-программа веб-сайта уже прошла чтениеwindow.navigator.webdriver
Зная, что сейчас вы используете эмулируемый браузер, какой смысл его скрывать?
Таким образом, даже если вы хотите выполнить этот оператор JavaScript, это должно произойти до того, как браузер запустит весь JavaScript, поставляемый с веб-сайтом.
Это наш текущий план.
Некоторые читатели могут подумать, что при написании плагина для браузера Chrome оператор JavaScript в плагине просто открывается перед открытием страницы веб-сайта, прежде чем запускать встроенный JavaScript.
Хотя этот метод может решить проблему, он немного хлопотный.Наш метод сегодня очень прост. с помощью GoogleChrome Devtools-Protocol(Chrome 开发工具协议)
короткое имяCDP
.
мы открытыОфициальная документация CPD, вы можете увидеть следующую команду:
Запускает данный скрипт непосредственно перед открытием каждого фрейма, до того, как скрипт фрейма был запущен.
С помощью этой команды мы можем передать фрагмент кода JavaScript и позволить Chrome просто открывать каждую страницу и выполнять данный фрагмент кода перед запуском кода JavaScript, поставляемого с веб-сайтом.
Итак, как вызывать команды CDP в Selenium? На самом деле это довольно просто, мы используемdriver.execute_cdp_cmd
. Согласно Селенуофициальная документация, передайте команду CDP и параметры для вызова:
Таким образом, мы можем написать следующий код:
from selenium.webdriver import Chrome
driver = Chrome('./chromedriver')
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
driver.get('http://exercise.kingname.info')
Эффект операции показан на следующем рисунке:
Идеально спрятанwindow.navigator.webdriver
. И ключевое утверждение:
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
Только нужно сделать это один раз, после этого, пока вы не закроете этоdriver
В открывшемся окне, независимо от того, сколько URL-адресов вы откроете, он автоматически выполнит этот оператор заранее, прежде чем все js, которые идут с веб-сайтом, скроют его.window.navigator.webdriver
.
Если кто-то запускает приведенный выше код, возникает следующая ошибка:
Затем обновите ChromeDriver. Более старые версии Chrome + ChromeDriver могут использовать только предыдущий метод, а не сегодняшний метод. Новая версия Chrome + ChromeDriver может использовать сегодняшний метод, но не старый. Это именно то, что он говорит:
Когда Бог закрыл для вас дверь, он тихо открыл для вас окно.
Хотя приведенный выше код можно использовать для достижения цели, для достижения лучшего эффекта скрытия вы можете продолжить добавлять две экспериментальные опции:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path='./chromedriver')
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
driver.get('http://exercise.kingname.info')