1. 概述
在考慮Web自動化時,Selenium通常是第一個出現的工具。它被廣泛用於自動化Web瀏覽器、測試應用程序,甚至從網站提取信息。
然而,隨着網站的不斷髮展,它們已經實施了各種反爬蟲檢測機制,以區分真實用户和自動化工具。如果我們嘗試執行一個Selenium腳本,並遇到諸如訪問阻止、重定向或CAPTCHA等障礙,那麼我們親身經歷了這一挑戰。
在本教程中,我們將研究在Selenium和Spring Boot中使用時,繞過最常見反爬蟲檢測的必要設置。
2. 設置 Spring Boot 項目
在編寫任何代碼之前,我們需要設置好我們的項目。我們將使用 Maven 進行依賴管理,因為它是在 Spring Boot 項目的標準配置中使用的。以下是我們在 <em pom.xml</em > 文件中需要的關鍵依賴項:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.18.1</version>
</dependency>這是 Selenium 的核心庫。為了確保與現代瀏覽器兼容並訪問高級功能,如 Chrome DevTools Protocol (CDP),我們需要使用最新版本。
3. 實現
現在我們將編寫代碼,使我們能夠使用 CDP 來繞過機器人檢測。
3.1. 創建 Webdriver
讓我們創建一個類 WebDriverFactory.java,用於配置和創建 ChromeDriver:
public class WebDriverFactory {
public static ChromeDriver createDriver() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-blink-features=AutomationControlled");
}
}首先,我們創建一個 <em >ChromeOptions</em> 對象。<strong >這允許我們在瀏覽器啓動時傳遞自定義參數</strong >。我們添加了參數–disable-blink-features=AutomationControlled`。這個簡單但有效的命令禁用了 Chrome 中的一項已知自動化指示功能。這將是我們的初步防禦措施:
public static ChromeDriver createDriver() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-blink-features=AutomationControlled");
ChromeDriver driver = new ChromeDriver(options);
}接下來,我們創建一個新的 ChromeDriver 實例,並傳入我們剛剛配置好的 options 對象。 這樣可以確保瀏覽器以第一個反檢測設置已就緒的狀態啓動:
public static ChromeDriver createDriver() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-blink-features=AutomationControlled");
ChromeDriver driver = new ChromeDriver(options);
Map<String, Object> params = new HashMap<>();
params.put("source", "Object.defineProperty(navigator, 'webdriver', { get: () => undefined })");
driver.executeCdpCommand("Page.addScriptToEvaluateOnNewDocument", params);
return driver;
}在驅動程序創建完成後,我們轉向更健壯的技術。我們使用 driver.executeCdpCommand()方法來執行 Chrome DevTools 協議 (CDP) 中的命令。該命令 Page.addScriptToEvaluateOnNewDocument在此處至關重要,它指示瀏覽器在每次加載新文檔(網頁)時運行特定的 JavaScript 代碼片段。
該代碼片段本身,Object.defineProperty(navigator, ‘webdriver’, { get: () => undefined }),是一個巧妙的代碼,它重新定義了 navigator.webdriver屬性。它不再返回自動瀏覽器為其默認的 true 值,而是返回 undefined,這正是人類瀏覽器所具有的值。
這是一種非常強大的方法,可以欺騙網站的機器人檢測腳本。
3.2. 搜索執行
現在我們已經實現了我們的 ChromeDriver,接下來我們來實現一個 GoogleSearchService 類,用於我們的自動化搜索:
public class GoogleSearchService {
private final WebDriver driver;
public GoogleSearchService(WebDriver driver) {
this.driver = driver;
}
public void navigateToGoogle() {
driver.get("https://www.google.com");
}
public void search(String query) {
WebElement searchBox = driver.findElement(By.name("q"));
searchBox.sendKeys(query);
searchBox.sendKeys(Keys.ENTER);
}
public String getPageTitle() {
return driver.getTitle();
}
public void quit() {
driver.quit();
}
}我們使用了標準的 Selenium 驅動程序 ,這有助於我們導航到 Google 搜索引擎。我們可以用任何其他公共網站替換它,以便測試我們的腳本。 命令使用其屬性名 (q) 來查找頁面上的搜索框元素。
這是一種基本但可靠的方式來定位元素。然後,使用命令 ,我們在搜索框中輸入“baeldung”,模擬用户的輸入。使用命令 ,模擬按下 鍵,提交搜索查詢。
3.3. 主執行流程
現在我們來看一下將所有內容聯繫在一起的主要類。<em>AvoidBotDetectionSelenium.java</em> 類作為主要的入口點,用於創建 <em>ChromeDriver</em>,初始化 <em>GoogleSearchService</em>,然後通過服務對象觸發後續的搜索操作:
public class AvoidBotDetectionSelenium {
public static void main(String[] args) {
ChromeDriver driver = WebDriverFactory.createDriver();
GoogleSearchService googleService = new GoogleSearchService(driver);
googleService.navigateToGoogle();
googleService.search("baeldung");
googleService.quit();
}
}我們使用 AvoidBotDetectionSelenium 類作為主要的入口點來協調我們的隱蔽瀏覽器自動化。該過程是分層的:首先,我們調用 WebDriverFactory.createDriver() 以獲取預先配置好的 ChromeDriver,該驅動程序已預先配置了反偵測功能(例如隱藏 navigator.webdriver 屬性)。
然後,該配置驅動程序傳遞給 GoogleSearchService,該服務執行核心自動化邏輯:使用 googleService.navigateToGoogle() 導航到 Google,並使用 googleService.search(“baeldung”) 模擬用户搜索。 googleService.quit() 確保瀏覽器已正確關閉,並釋放系統資源,從而完成乾淨、專業的執行流程。
最後,我們需要考慮無頭瀏覽器和有頭瀏覽器的選擇。 雖然我們通常使用無頭瀏覽器以其速度和效率,但某些網站具有高級的檢測機制,可以識別它們。 在這些情況下,我們發現以可見模式(在屏幕上顯示的模式)運行瀏覽器更可靠。 這是在速度和隱蔽性之間進行權衡,並且是我們根據目標網站的特定行為所需要做出的決定。
4. 合法且正確的解析網站的方法
現在我們已經瞭解瞭如何通過技術手段繞過檢測,接下來我們談談責任。 即使我們能夠繞過檢測,也不意味着我們應該這樣做。 許多網站在其《服務條款》中明確禁止自動抓取,違反這些條款可能會使我們面臨法律風險。
此外,我們還需要尊重互聯網的未公開規則。 我們可以使用網站的 robots.txt 文件作為指導,它是由網站所有者發出的明確信號,指示哪些內容可以抓取,哪些內容則禁止抓取。 忽略這些規則通常被認為是開發者社區中的不道德行為。 當我們考慮更安全、更專業的替代方案時,我們應該首先尋找公共 API。
許多公司提供這些,專門用於對他們的數據進行結構化和授權訪問。 這對我們和網站都有利,因為它可以讓我們以乾淨的格式獲得所需的數據,同時尊重網站的基礎設施。 如果沒有公共 API 可用,我們也可以在網站明確允許或提供公開端點的情況下,使用像 Jsoup 或 Selenium 這樣的抓取庫。
最後,在開始任何抓取項目之前,始終檢查我們是否需要的數據是否已經可用。 在像 Kaggle 這樣的平台上以及各種政府網站上,有大量的公開數據集。 這可以節省時間和確保我們不會違反條款,因為一個完美且合法的替代方案已經存在於我們的使用中。
5. 結論
使用 Selenium 自動化瀏覽器有時會令人沮喪,因為我們經常被反爬蟲檢測機制所阻止。在本教程中,我們看到了如何將適當的 ChromeOptions 設置與 Chrome DevTools 協議 (CDP) 的功能相結合,從而構建一個強大且隱蔽的自動化工具。
我們所涵蓋的技術,例如禁用 AutomationControlled 和欺騙 navigator.webdriver 屬性,對於使我們的自動化腳本與人類用户 indistinguishable 至關重要。由於我們已經解鎖了繞過防禦機制的潛力,讓我們致力於以道德和負責任的方式使用它。始終尊重網站的 robots.txt 文件和 服務條款,並注意我們的腳本對他們服務器的影響。
如往常一樣,本文的代碼可在 GitHub 上找到:https://github.com/eugenp/tutorials/tree/master/testing-modules/selenium。