
前言
今天要推薦的是 Html Agility Pack (HAP),一款強大的 .NET HTML 解析函式庫,能在【C#】與【Unity】專案中輕鬆處理網頁結構,實現【靜態爬蟲】與【資料擷取】!
無論是要【批次擷取鏈接】、【解析節點屬性】,還是利用 XPath / LINQ 語法靈活查詢網頁內容,HAP 都能提供【高效】又【穩定】的解決方案。
對於需要在 Unity 中【結合後端資料】、【處理外部靜態網頁】,或是打造遊戲內嵌資訊系統的開發者來說,這是一個非常實用的插件神器。

Unity Html Agility Pack 插件介紹
Html Agility Pack 是一個長期維護的開源函式庫,支援多種 .NET 平台,包括【.NET Framework】、【.NET Core】、【.NET Standard】,甚至可直接用於 Unity 2018+。
它的特色是能夠處理即使【結構不完整】或【有錯誤】的 HTML 文件,並提供完整的 API 來操作節點樹。
HAP 的三大核心組件包括:
- HtmlWeb:用於下載網頁。
- HtmlDocument:HTML 文件容器,可進行【載入】與【解析】。
- HtmlNode:節點對象,提供【存取】與【遍歷】操作。
透過這些模組,開發者能在 Unity 環境中快速建立【爬蟲】或【解析工具】,並無縫整合【遊戲】或【應用程式】。

功能特色
- 靈活的 HTML 載入方式
支援從【URL】、【字串】、【檔案載入 HTML】,並能容錯處理非標準 HTML。 - XPath / LINQ 雙重查詢支援
提供強大的 XPath 語法精準查詢,也能透過 LINQ 寫法快速篩選節點。 - 跨平台相容性佳
基於 .NET Standard 2.0,兼具【Unity】與【.NET 應用】相容性,解析大型 HTML 仍能穩定高效。
適用場景
- 遊戲內嵌爬蟲資訊系統
例如在 Unity 遊戲中,自動抓取最新【活動公告】或【攻略內容】,直接展示在遊戲內 UI。 - 【資料擷取】與【自動化測試】
在【開發工具】或【編輯器插件】中,用於批量抓取靜態網頁資料,如【排行榜】、【新聞】、【素材】。 - 跨平台應用擴充
不僅能在 Unity 遊戲內使用,也能擴展到後端服務,統一處理【HTML】與【資料流】,提升開發效率。

Unity Html Agility Pack 安裝
1. 從 NuGet 下載 HtmlAgilityPack 包
官方下載連結:Html Agility Pack
選擇版本點擊下載

2. 取得 HtmlAgilityPack.dll
下載的是 nupkg 文件,解壓縮後在 lib 資料夾下, 有不同版本的不同 .NET 版本對應的包。

各版本核心區別
建議大多數 Unity 專案選擇 **.NET Standard 2.0** 版本,以平衡相容性和功能性。
僅當明確需要新特性時再考慮 .NET 8.0 版本。

將 HtmlAgilityPack. DLL 檔案放入 Unity 專案的 Assets/Plugins 資料夾中即可。

Unity Html Agility Pack 常用操作
1. 載入 HTML
// 從 URL 加載
var web = new HtmlWeb();
HtmlDocument doc = web.Load("https://example.com");
// 從字符串加載
var doc = new HtmlDocument();
doc.LoadHtml(htmlContent);
// 從文件加載(Unity 使用 Application.dataPath)
doc.Load("path/to/file.html");
2. 查詢方式
2.1 使用 XPath 查詢(建議)
// 獲取所有鏈接
HtmlNodeCollection links = doc.DocumentNode.SelectNodes("//a[@href]");
if (links != null)
{
foreach (HtmlNode link in links)
{
string href = link.GetAttributeValue("href", "");
string text = link.InnerText.Trim();
Debug.Log($"鏈接: {text} -> {href}");
}
}
// 獲取特定 class 的元素
var products = doc.DocumentNode.SelectNodes("//div[@class='productitem']");
2.2 使用 LINQ 查詢
using System.Linq;
var titles = doc.DocumentNode.Descendants("h2")
.Where(node => node.GetAttributeValue("class", "") == "title")
.Select(node => node.InnerText.Trim())
.ToList();
3. 常用查詢操作
3.1 選擇節點
// 通過 XPath 選擇節點
HtmlNodeCollection nodes =
doc.DocumentNode.SelectNodes("//div[@class='content']");
// 選擇單個節點
HtmlNode node = doc.DocumentNode.SelectSingleNode("//h1");
3.2 取得屬性值
string href = node.GetAttributeValue("href", ""); // 第二個參數是默認值
string id = node.Attributes["id"]?.Value;
3.3 遍歷節點
foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]"))
{
string hrefValue = link.GetAttributeValue("href", string.Empty);
Debug.Log(hrefValue);
}
3.4 取得節點內容
string innerText = node.InnerText; // 不含 HTML 標簽的文本
string innerHtml = node.InnerHtml; // 包含 HTML 標簽
string outerHtml = node.OuterHtml; // 包含節點自身及其內容
Unity Html Agility Pack XPath 文法
XPath (XML Path Language) 是一種用於在 XML 和 HTML 文件中定位節點的查詢語言,Html Agility Pack (HAP) 完全支援 XPath 查詢。
掌握 XPath 是高效使用 HAP 的關鍵。
1. 節點類型
- 元素節點:HTML 標籤(如 <div>、<a>)
- 屬性節點:元素的屬性(如 href、class)
- 文字節點:元素內的文字內容
- 文檔節點:整個文檔
2. 路徑表達式
XPath 使用路徑表達式來選取節點,類似於檔案系統路徑:
- / 從根節點開始
- // 從目前節點選擇匹配節點,不考慮位置
- . 當前節點
- .. 父節點
- @ 選取屬性
3. 節點選擇
4. 謂語(Predicates)
用於尋找特定節點,放在方括號中:
//div[1] // 第一個 <div>
//div[last()] // 最後一個 <div>
//div[position()<3] // 前兩個 <div>
//a[@href] // 帶有 href 屬性的 <a>
//div[@class='main'] // class 為 "main" 的 <div>
5. 通配符
6. 多條件篩選
//div[@class='article' and @data-id='123']
//a[contains(@class,'btn') or @type='submit']
7. 文字內容匹配
//h1[text()='Welcome'] // 精確匹配
//p[contains(text(),'Hello')] // 包含文本
//span[starts-with(text(),'Copyright')]
8. 軸(Axes)選擇
9. 函數
//div[contains(@class, 'header')] // 屬性包含特定字符串
//a[starts-with(@href, 'https')] // 屬性以特定字符串開頭
//p[string-length(text()) > 100] // 文本長度大於 100
count(//div) // 統計 div 數量
Unity Html Agility Pack 快速從瀏覽器取得 XPath
實際情況我們其實可以直接從瀏覽器複製取得 XPath,而不需要自己寫。

Unity Html Agility Pack XPath 使用範例
1. 案例
例如我想要尋找 id="liveroom__sidebar" 的 div 元素內部所有 class="status" 的子元素(無論巢狀層級),可以使用以下 XPath 表達式:
//div[@id='liveroom__sidebar']//*[contains(@class, 'status')]
或精確匹配(如果 class 只有 'status'):
//div[@id='liveroom__sidebar']//*[@class='status']
關鍵點說明
- // 雙斜線:表示搜尋所有後代節點(不限層級)
- * 星號:符合任何標籤名(div/span/p 等)
- contains(@class, 'status'):
- 比 @class='status' 更靈活
- 能匹配複合 class 如 <div class="status active">
- 精確匹配場景:
- 如果確定 class 只有 "status"(沒有其他 class),可以用 @class='status'
- 如果確定 class 只有 "status"(沒有其他 class),可以用 @class='status'
2. 常見用法
Unity Html Agility Pack HAP 中的實際應用範例
1. 獲取所有鏈接
var links = doc.DocumentNode.SelectNodes("//a[@href]");
foreach (HtmlNode link in links)
{
string href = link.GetAttributeValue("href", "");
Console.WriteLine(href);
}
2. 取得特定 class 的內容
var nodes =
doc.DocumentNode.SelectNodes("//div[contains(@class,'product')]");
foreach (HtmlNode node in nodes)
{
string title = node.SelectSingleNode(".//h3").InnerText;
string price =
node.SelectSingleNode(".//span[@class='price']").InnerText;
}
3. 處理表格數據
var rows = doc.DocumentNode.SelectNodes("//table[@id='data']/tr");
foreach (HtmlNode row in rows)
{
var cells = row.SelectNodes("./td");
if (cells != null && cells.Count >= 2)
{
string name = cells[0].InnerText.Trim();
string value = cells[1].InnerText.Trim();
}
}
Unity Html Agility Pack 性能優化
- 盡量使用具體路徑而非 // 開頭
- 優先使用屬性而非文字內容定位
- 快取常用 XPath 查詢結果
Unity Html Agility Pack 實戰
1. 爬取靜態網頁文本數據
例如我實現爬取自己的部落格的簡介數據,按 f12 查看 html 程式碼結構。

程式碼如下
using System.Collections;
using HtmlAgilityPack;
using UnityEngine;
public class WebCrawler : MonoBehaviour
{
// 目標網站URL(請替換為實際網址)
public string targetUrl = "https://xiangyu.blog.csdn.net";
void Start()
{
StartCoroutine(FetchWebData());
}
IEnumerator FetchWebData()
{
// 從URL加載HTML文檔
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(targetUrl);
//個人簡介(這里故意分兩段獲取只是為了演示效果)
HtmlNode nodeIntro =doc.DocumentNode.SelectSingleNode("//div[@class='user-profile-head-info-b']");
string strIntro = nodeIntro.SelectSingleNode("//p[contains(@class, 'introduction-fold')]").InnerText;
Debug.Log(strIntro);
// 博客簡介和博客描述
HtmlNodeCollection nodes =doc.DocumentNode.SelectNodes("//div[@class='user-profile-wrapper-box']");
if (nodes != null)
{
foreach (HtmlNode node in nodes)
{
Debug.Log(node.InnerText);
}
}
yield return null;
}
}
結果

2. 爬取並保持圖片數據
using UnityEngine;
using UnityEngine.Networking;
using System.IO;
using HtmlAgilityPack;
using System.Collections;
using System.Web;
public class SimpleImageDownloader : MonoBehaviour
{
public string url = "https://cn.bing.com/images/search?q=%E5%8F%AF%E7%88%B1%E5%9B%BE%E7%89%87&form=HDRSC2&first=1&cw=1177&ch=917"; // 目標網頁
public string saveFolder = "DownloadedImages"; // 保存文件夾
void Start()
{
StartCoroutine(DownloadImages());
}
IEnumerator DownloadImages()
{
// 1. 下載網頁
UnityWebRequest webRequest = UnityWebRequest.Get(url);
yield return webRequest.SendWebRequest();
if (webRequest.result != UnityWebRequest.Result.Success)
{
Debug.LogError("網頁加載失敗: " + webRequest.error);
yield break;
}
// 2. 解析圖片
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(webRequest.downloadHandler.text);
var imgNodes = htmlDoc.DocumentNode.SelectNodes("//img[@src]");
if (imgNodes == null) yield break;
// 3. 創建保存目錄
string savePath = Path.Combine(Application.dataPath, "../", saveFolder);
Directory.CreateDirectory(savePath);
// 4. 下載圖片
foreach (var imgNode in imgNodes)
{
string imgUrl = imgNode.GetAttributeValue("src", "");
if (!imgUrl.StartsWith("http"))
{
// 處理相對路徑
imgUrl = new System.Uri(new System.Uri(url), imgUrl).AbsoluteUri;
}
UnityWebRequest imgRequest =UnityWebRequestTexture.GetTexture(imgUrl);
yield return imgRequest.SendWebRequest();
if (imgRequest.result == UnityWebRequest.Result.Success)
{
Texture2D texture = DownloadHandlerTexture.GetContent(imgRequest);
byte[] bytes = texture.EncodeToPNG();
string fileName = Path.GetFileName(imgUrl.Split('?')[0])+".png";
if (string.IsNullOrEmpty(fileName)) fileName = "image.png";
File.WriteAllBytes(Path.Combine(savePath, fileName), bytes);
Debug.Log("已保存: " + fileName);
}
else
{
Debug.LogWarning("下載失敗: " + imgUrl);
}
}
Debug.Log("圖片下載完成!保存在" + savePath);
}
}
結果

Unity Html Agility Pack 網頁解析大師相關網站 & 插件下載點
【Html Agility Pack】
官方網站:Html Agility Pack
官方下載連結:Html Agility Pack
————————————————
更多好用插件:【Unity 好用插件推薦】持續更新,一起讓遊戲開發事半功倍!
本文原創(或整理)於亞洲電玩通,未經作者與本站同意不得隨意引用、轉載、改編或截錄。
特約作家簡介
支持贊助 / DONATE
亞洲電玩通只是很小的力量,但仍希望為復甦台灣遊戲研發貢獻一點動能,如果您喜歡亞洲電玩通的文章,或是覺得它們對您有幫助,歡迎給予一些支持鼓勵,不論是按讚追蹤或是贊助,讓亞洲電玩通持續產出,感謝。
BTC |
![]() |
bc1psp8nnerlepv56nyfha6mqwnp3yr7qqjdw44c6qt5lx5r2urma7fqykxvwj |
|
ETH |
![]() |
0xB2231557bc418201922DD7C2673ec97E67E35F83 |
|
TRON |
![]() |
TAomNj4L6vMJuaJmbWUdmT1uAWYPf9vDjp |








