如何使用 Selenium 取得 JSON 回應
1.概述
在 Web 開發中,網頁使用 JavaScript 從 API 動態取得資料的情況並不少見。有時,我們可能想要擷取這些 API 傳回的 JavaScript 物件表示法 (JSON) 回應,以便自動擷取資料、驗證資料或執行測試。對於此類任務,我們可以使用 Selenium WebDriver 之類的工具來擷取 JSON 回應。然而,這並不總是那麼簡單。
在本教程中,我們將使用一種簡單實用的方法來使用 Selenium 來取得 JSON 回應。
2. 基礎知識與先決條件
Selenium 專為瀏覽器自動化而設計,通常與按鈕、輸入欄位和連結等元素進行互動。但是,它不直接提供用於捕獲原始網路回應的 API。
為了示範解決方法,我們可以使用 Selenium 連續執行多個任務:
- 載入頁面
- 等待 JSON 顯示在頁面上
- 使用驅動程式提取內容
具體來說,該方法適用於透過 fetch 或 XHR 傳回的頁面呈現的 JSON 。
在繼續之前,我們需要確保安裝了幾個先決條件:
- Java 11 或更高版本
- Maven
- Chrome 瀏覽器
- ChromeDriver 與 Chrome 版本匹配
現在,讓我們繼續建立一個獲取 JSON 物件的簡單 HTML 頁面,以便我們可以使用 Java Selenium 捕獲 JSON。
3. 項目設定
對於這個項目,我們使用 Maven 來管理依賴項。
首先,讓我們建立一個 Maven 專案結構selenium-json-demo
:
$ mvn archetype:generate -DgroupId=com.example -DartifactId=selenium-json-demo -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
[INFO] Scanning for projects...
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.150 s
[INFO] Finished at: 2025-09-02T08:01:51+03:00
[INFO] ------------------------------------------------------------------------
一旦上述指令成功建立了 Maven 專案結構,我們就可以導航到它:
$ cd selenium-json-demo
在專案目錄中,我們適當更新pom.xml
檔:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>selenium-json-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>selenium-json-demo</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- Selenium WebDriver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.25.0</version>
</dependency>
<!-- JUnit for testing (optional) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<mainClass>com.example.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
pom.xml
檔案設定了 Java 11 編譯器、Selenium WebDriver 依賴項以及用於執行主類別的 Maven exec 插件。在此配置中, <dependency>
標籤會拉取用於驅動瀏覽器和 JUnit 的 Selenium 庫(如果我們以後想要實作測試案例的話)。同時, <build>
部分新增了 exec-maven-plugin,使我們能夠使用mvn exec:java
執行主類別 ( com.example.App
)。如果沒有這個插件,Maven 就不知道如何直接從命令列啟動 Selenium 程式碼。
4.編寫HTML測試頁面
在專案目錄中,讓我們建立一個簡單的 HTML 頁面test.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test JSON Fetch</title>
</head>
<body>
<h1>Testing JSON Fetch</h1>
<pre id="output"></pre>
<script>
fetch('https://jsonplaceholder.typicode.com/todos/1')
.then(response => response.json())
.then(data => {
document.getElementById('output').textContent = JSON.stringify(data, null, 2);
})
.catch(error => console.error('Error fetching JSON:', error));
</script>
</body>
</html>
那麼,讓我們來分析一下:
-
fetch
:從https://jsonplaceholder.typicode.com/todos/1
取得 JSON -
document.getElementById('output').textContent
:呈現 JSON -
<pre>
:用於保留格式以便於閱讀的標籤
透過在本地提供此文件,我們模擬了動態獲取 JSON 並渲染到頁面上的場景。 <pre>
標籤保留了格式,因此 Selenium 稍後可以一次性捕獲整個 JSON 字串。因此,該方法反映了儀表板或開發者終端以純文字形式顯示 JSON 回應的真實情況。
5.編寫 Java Selenium 程式碼
現在,讓我們更新src/main/java/com/example
下的App.java
檔:
package com.example;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class App {
public static void main(String[] args) {
// Optional: Set ChromeDriver path if not in system PATH
// System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
WebDriver driver = new ChromeDriver();
try {
// Open local test page
driver.get("http://localhost:8000/test.html");
// Wait briefly for JSON to load
Thread.sleep(2000); // 2 seconds
// Capture JSON from <pre> element
String json = driver.findElement(By.id("output")).getText();
System.out.println("Captured JSON:\n" + json);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
driver.quit();
}
}
}
我們來分析一下上面的程式碼:
-
WebDriver driver = new ChromeDriver()
:啟動 Chrome -
driver.get(“http://localhost:8000/test.html”)
:開啟頁面 -
Thread.sleep(2000)
:等待 JSON 載入 -
driver.findElement(By.id(“output”)).getText()
:提取 JSON 文本
此時,我們應該可以運行該專案了。
6.運行項目
當然,我們需要提供 HTML 文件,以便 ChromeDriver 可以透過 HTTP 載入它。
從專案目錄中,讓我們為test.html
啟動一個本機伺服器:
$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
上面我們使用了 Python 內建的 HTTP 伺服器。其實任何簡單的靜態伺服器都可以,因為關鍵在於 ChromeDriver 只能透過http://
或https://
載入文件,而無法直接從我們的檔案系統使用file://
載入。
一旦本地伺服器設定好,我們就可以編譯專案:
$ mvn clean compile
[INFO] Scanning for projects...
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.752 s
[INFO] Finished at: 2025-09-02T10:32:19+03:00
[INFO] ------------------------------------------------------------------------
編譯專案後,我們可以執行Selenium程式:
$ mvn exec:java
[INFO] Scanning for projects...
...
Captured JSON:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 44.448 s
[INFO] Finished at: 2025-09-02T10:38:15+03:00
[INFO] ------------------------------------------------------------------------
在輸出中,經常會遇到 CDP 版本警告:
WARNING: Unable to find version of CDP to use for 139.0.7258.66. You may need to include a dependency on a specific version of the CDP using something similar to `org.seleniumhq.selenium:selenium-devtools-v86:4.25.0` where the version ("v86") matches the version of the chromium-based browser you're using and the version number of the artifact is the same as Selenium's.
在這種情況下,任何 CDP 版本警告都是無害的。
[WARNING] thread Thread[UrlChecker-2,5,com.example.App] was interrupted but is still alive after waiting at least 14994msecs
此外,我們還會遇到線程警告:
[WARNING] thread Thread[UrlChecker-2,5,com.example.App] was interrupted but is still alive after waiting at least 14994msecs
它們的發生是因為 Maven 試圖終止由 Selenium 建立的執行緒。
7. 理解輸出
我們捕獲的 JSON 正是 fetch API 傳回並在頁面上呈現的內容。
解釋一下,該方法的工作原理如下:
- Selenium 與瀏覽器交互
- JSON 在 DOM 中呈現,具體來說是
<pre>
元素 - Selenium 提取文字內容,因此我們得到完整的 JSON 回應
因此,只要頁面呈現 JSON,該方法就可以跨瀏覽器運行,並且不需要複雜的代理,這使得初學者也可以輕鬆實現。
相反,該方法的局限性在於它僅適用於頁面中渲染的 JSON。此外,它不適用於不更新 DOM 的後台 API 呼叫。如果我們需要攔截從未出現在 DOM 中的原始 API 回應,則需要使用 Selenium DevTools 等進階工具或 BrowserMob 等代理。
8. 結論
在本文中,我們研究如何使用 Selenium 從 HTML 頁面取得基本的 JSON 回應。
透過利用頁面渲染 API 回應的方式,我們可以使用 Selenium WebDriver 載入頁面、等待回應,並直接從 DOM 中提取 JSON。在本例中,我們能夠透過提供靜態test.html
檔案並使用 Selenium WebDriver 定位並提取<pre>
標籤內的文本,直接在 Java 中取得並列印 JSON。
現在,我們已經有一個可以運行的 Java Selenium 專案的最小設置,可以從網頁捕獲 JSON。
與往常一樣,本文的源代碼可在 GitHub 上取得。