【推薦100個unity插件】使用C#或者unity實現爬蟲爬取靜態網頁數據——Html Agility Pack (HAP)庫和XPath 語法的使用

文章目錄

  • 前言
  • 一、安裝HtmlAgilityPack
    • 1、從NuGet下載HtmlAgilityPack包
    • 2、獲取HtmlAgilityPack.dll
  • 二、HtmlAgilityPack常用操作
    • 1、加載 HTML
    • 2、查詢方式
      • 2.1 使用 XPath 查詢(推薦)
      • 2.2 使用 LINQ 查詢
    • 3、常用查詢操作
      • 3.1 選擇節點
      • 3.2 獲取屬性值
      • 3.3 遍歷節點
      • 3.4 獲取節點內容
  • 三、XPath 語法
    • 1、節點類型
    • 2、路徑表達式
    • 3、節點選擇
    • 4、謂語(Predicates)
    • 5、通配符
    • 6、多條件篩選
    • 7、文本內容匹配
    • 8、軸(Axes)選擇
    • 9、函數
  • 四、快捷從瀏覽器獲取XPath
  • 五、XPath使用示例
    • 1、案例
    • 2、常見用法
  • 六、HAP 中的實際應用示例
      • 1. 獲取所有鏈接
      • 2. 獲取特定 class 的內容
      • 3. 處理表格數據
  • 七、性能優化
  • 八、實戰
    • 1、爬取靜態網頁文本數據
    • 2、爬取并保持圖片數據
  • 專欄推薦
  • 完結

前言

Html Agility Pack (HAP) 是一個強大的 .NET HTML 解析庫,特別適合在 C# 和 Unity 中實現爬蟲功能。它支持有缺陷的 HTML 解析、XPath 查詢和 LINQ 操作。

核心組件

  • HtmlWeb:網頁下載器

  • HtmlDocument:HTML 文檔容器

  • HtmlNode:HTML 節點對象

  • github:https://github.com/zzzprojects/html-agility-pack?tab=readme-ov-file

一、安裝HtmlAgilityPack

1、從NuGet下載HtmlAgilityPack包

https://www.nuget.org/packages/HtmlAgilityPack/#versions-body-tab

選擇版本點擊下載
在這里插入圖片描述

2、獲取HtmlAgilityPack.dll

下載的是nupkg文件,解壓后在lib文件夾下, 有不同版本的不同.NET版本對應的包
在這里插入圖片描述
各版本核心區別

特性/版本.NET 8.0版.NET Standard 2.0版.NET Framework 3.5版
兼容性僅支持.NET 6.0+跨平臺(兼容.NET Core/.NET 5+/Unity等)僅限傳統.NET Framework
性能最優(AOT優化)中等較低
API完整性最新API(如CSS選擇器)大部分核心功能基礎功能
Unity支持情況需Unity 2021.2+最佳支持(推薦)舊版Unity(2018-2020)
NuGet包名HtmlAgilityPackHtmlAgilityPack.NetCore或標準版HtmlAgilityPack

建議大多數Unity項目選擇**.NET Standard 2.0**版本,平衡兼容性和功能性。僅當明確需要新特性時再考慮.NET 8.0版本。
在這里插入圖片描述
將HtmlAgilityPack.DLL文件放入Unity項目的Assets/Plugins文件夾中即可
在這里插入圖片描述

二、HtmlAgilityPack常用操作

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='product-item']");

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; // 包含節點自身及其內容

三、XPath 語法

XPath (XML Path Language) 是一種用于在 XML 和 HTML 文檔中定位節點的查詢語言,Html Agility Pack (HAP) 完全支持 XPath 查詢。掌握 XPath 是高效使用 HAP 的關鍵。

1、節點類型

  • 元素節點:HTML 標簽(如 <div><a>
  • 屬性節點:元素的屬性(如 hrefclass
  • 文本節點:元素內的文本內容
  • 文檔節點:整個文檔

2、路徑表達式

XPath 使用路徑表達式來選取節點,類似于文件系統路徑:

  • / 從根節點開始
  • // 從當前節點選擇匹配節點,不考慮位置
  • . 當前節點
  • .. 父節點
  • @ 選取屬性

3、節點選擇

表達式說明示例
nodename選取所有該名稱的節點div 選擇所有 <div>
/從根節點開始/html/body/div
//從任意位置選擇//div 選擇所有 <div>
.當前節點./span 當前節點的子 <span>
..父節點../div 父節點下的 <div>
@選擇屬性@href 選擇 href 屬性

4、謂語(Predicates)

用于查找特定節點,放在方括號中:

//div[1]            // 第一個<div>
//div[last()]       // 最后一個<div>
//div[position()<3] // 前兩個<div>
//a[@href]          // 帶有href屬性的<a>
//div[@class='main'] // class為"main"的<div>

5、通配符

通配符說明示例
*匹配任何元素節點//* 所有元素
@*匹配任何屬性節點//div[@*] 帶任意屬性的
node()匹配任何類型節點//div/node() div的所有子節點

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)選擇

說明示例
child::子節點(默認軸,可省略)//div/child::span//div/span
parent::父節點//span/parent::div
ancestor::所有祖先節點//span/ancestor::div
descendant::所有后代節點//div/descendant::span
following::文檔中當前節點之后的所有節點//div/following::span
preceding::文檔中當前節點之前的所有節點//div/preceding::span
following-sibling::同一層級之后的兄弟節點//li/following-sibling::li
preceding-sibling::同一層級之前的兄弟節點//li/preceding-sibling::li

9、函數

//div[contains(@class, 'header')]  // 屬性包含特定字符串
//a[starts-with(@href, 'https')]   // 屬性以特定字符串開頭
//p[string-length(text()) > 100]   // 文本長度大于100
count(//div)                       // 統計div數量

四、快捷從瀏覽器獲取XPath

實際情況我們其實可以直接從瀏覽器復制獲取XPath,而不需要自己寫
在這里插入圖片描述

五、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'

2、常見用法

/					從根節點選取。
//					從匹配選擇的當前節點選擇文檔中的節點,而不考慮它們的位置。
.					選取當前節點。
..					選取當前節點的父節點。
@					選取屬性
/bookstore/*		選取 bookstore 元素的所有子元素
//*					選取文檔中的所有元素
//title[@*]			選取所有帶有屬性的 title 元素//div/a/@href				獲取a標簽的href的值
//div/a/text()					獲取a標簽的文本內容
/div/book[1]				選取屬于div子元素的第一個 book 元素。
/div/book[last()]			選取屬于 div 子元素的最后一個 book 元素。
/div/book[last()-1]			選取屬于 div子元素的倒數第二個 book 元素。
//title[@lang]				選取所有擁有名為 lang 的屬性的 title 元素。
//title[@name='a']			選取所有 title 元素,且這些元素擁有值為 a的 name 屬性。
/div/book[price>35.00]		選取 div元素的所有 book 元素,且其中的 price 元素的值須大于 35.00
//book/title | //book/price	選取 book 元素的所有 title 和 price 元素。

六、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();}
}

七、性能優化

  • 盡量使用具體路徑而非 // 開頭
  • 優先使用屬性而非文本內容定位
  • 緩存常用 XPath 查詢結果

八、實戰

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游戲開發入門到精通——C#篇】
【unity游戲開發入門到精通——unity通用篇】
【unity游戲開發入門到精通——unity3D篇】
【unity游戲開發入門到精通——unity2D篇】
【unity實戰】
【制作100個Unity游戲】
【推薦100個unity插件】
【實現100個unity特效】
【unity框架/工具集開發】
【unity游戲開發——模型篇】
【unity游戲開發——InputSystem】
【unity游戲開發——Animator動畫】
【unity游戲開發——UGUI】
【unity游戲開發——聯網篇】
【unity游戲開發——優化篇】
【unity游戲開發——shader篇】
【unity游戲開發——編輯器擴展】
【unity游戲開發——熱更新】
【unity游戲開發——網絡】

完結

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果學習過程中遇到任何問題,也歡迎你評論私信找我。

贈人玫瑰,手有余香!如果文章內容對你有所幫助,請不要吝嗇你的點贊評論和關注,你的每一次支持都是我不斷創作的最大動力。當然如果你發現了文章中存在錯誤或者有更好的解決方法,也歡迎評論私信告訴我哦!
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89720.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89720.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89720.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用 urllib 開啟爬蟲之門:從零掌握網頁數據抓取

在數字時代&#xff0c;數據就是力量。作為一名社會工作者&#xff0c;或許你想了解城市服務資源&#xff1b;作為一個編程初學者&#xff0c;你可能希望從網頁中自動提取新聞、課程或公開數據。今天&#xff0c;我們就來講一講 Python 標準庫中的一把“鑰匙”——urllib 庫&am…

Spring Boot 訂單超時自動取消的 3 種主流實現方案

Spring Boot 訂單超時自動取消的 3 種主流實現方案關鍵詞&#xff1a;Spring Boot、訂單超時、延遲任務、RabbitMQ、Redis、定時任務在電商、外賣、票務等業務中&#xff0c;“下單后若 30 分鐘未支付則自動取消”是一道經典需求。實現方式既要保證 實時性&#xff0c;又要在 高…

0401聚類-機器學習-人工智能

文章目錄一 無監督學習什么是無監督學習&#xff1f;核心特點&#xff1a;無監督學習的主要類型1. 聚類分析 (Clustering)2. 降維 (Dimensionality Reduction)3. 關聯規則學習 (Association Rule Learning)4. 異常檢測 (Anomaly Detection)5. 密度估計 (Density Estimation)二 …

基礎神經網絡模型搭建

nn 包提供通用深度學習網絡的模塊集合&#xff0c;接收輸入張量&#xff0c;計算輸出張量&#xff0c;并保存權重。通常使用兩種途徑搭建 PyTorch 中的模型&#xff1a;nn.Sequential和 nn.Module。 nn.Sequential通過線性層有序組合搭建模型&#xff1b;nn.Module通過__init__…

基于單片機出租車計價器設計

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 本設計實現了一種基于單片機的智能化出租車計價系統。系統以單片機為核心處理器&#xff0c;集成…

134. Java 泛型 - 上限通配符

文章目錄134. Java 泛型 - 上限通配符 (? extends T)**1. 什么是上限通配符 (? extends T)&#xff1f;****2. 為什么使用 ? extends T&#xff1f;****3. 示例&#xff1a;使用 ? extends T 進行數據讀取****? 示例 1&#xff1a;計算數值列表的總和****4. 注意事項&…

【1】YOLOv13 AI大模型-可視化圖形用戶(GUI)界面系統開發

【文章內容適用于任意目標檢測任務】【GUI界面系統不局限于YOLOV13&#xff0c;主流YOLO系列模型同樣適用】本文以車輛行人檢測為背景&#xff0c;介紹基于【YOLOV13模型】和【AI大模型】的圖形用戶&#xff08;GUI&#xff09;界面系統的開發。助力大論文實現目標檢測模型的應…

小程序常用api

1. wx.request - 發起網絡請求 用于向服務器發送 HTTP 請求&#xff0c;獲取數據或提交表單。 // 示例&#xff1a;GET 請求獲取數據 wx.request({url: https://api.example.com/data, // 替換為實際 API 地址method: GET,success: (res) > {console.log(請求成功, res.da…

PaliGemma 2-輕量級開放式視覺語言模型

PaliGemma 2是輕量級開放式視覺語言模型 (VLM)&#xff0c;靈感源自 PaLI-3&#xff0c;基于 SigLIP 視覺模型和 Gemma 語言模型等開放式組件。PaliGemma 同時接受圖片和文本作為輸入&#xff0c;并且可以回答有關圖片的詳細問題和背景信息。PaliGemma 2 提供 30 億、100 億和 …

騰訊云云服務器深度介紹

以下是圍繞騰訊云云服務器&#xff08;CVM&#xff09;的詳細介紹與推薦文章&#xff0c;結合其核心優勢、應用場景及技術特性&#xff0c;為不同用戶群體提供參考&#xff1a; &#x1f680; 一、產品定位與核心價值 騰訊云云服務器&#xff08;Cloud Virtual Machine, CVM&a…

Ceph OSD.419 故障分析

Ceph OSD.419 故障分析 1. 問題描述 在 Ceph 存儲集群中&#xff0c;OSD.419 無法正常啟動&#xff0c;系統日志顯示服務反復重啟失敗。 2. 初始狀態分析 觀察到 OSD.419 服務啟動失敗的系統狀態&#xff1a; systemctl status ceph-osd419 ● ceph-osd419.service - Ceph obje…

MySQL持久化原理及其常見問題

目錄 MySQL刷盤原理 臟頁和干凈頁 MySQL出現短暫的堵塞SQL現象 情況分析 應對措施 數據庫表中數據刪除原理 刪除表中數據數據庫空間大小不會改變 情況分析 應對措施 MySQL刷盤原理 一般主要分為兩個步驟 內存更新和 redo log 記錄是同一事務修改的兩個必要操作&#…

VSCode中Cline無法正確讀取終端的問題解決

出現的問題是&#xff1a;Cline 無法正確讀取終端輸出。 Shell Integration Unavailable Cline won’t be able to view the command’s output. Please update VSCode (CMD/CTRL Shift P → “Update”) and make sure you’re using a supported shell: zsh, bash, fish, o…

scalelsd 筆記 線段識別 本地部署 模型架構

ant-research/scalelsd | DeepWiki https://arxiv.org/html/2506.09369?_immersive_translate_auto_translate1 https://gitee.com/njsgcs/scalelsd https://github.com/ant-research/scalelsd https://huggingface.co/cherubicxn/scalelsd 模型鏈接&#xff1a; https…

Python, C ++開發個體戶/個人品牌打造APP

個體戶/個人品牌打造APP開發方案&#xff08;Python C&#xff09;一、技術選型與分工1. Python- 核心場景&#xff1a;后端API開發、數據處理、內容管理、第三方服務集成&#xff08;如社交媒體分享、支付接口&#xff09;。- 優勢&#xff1a;開發效率高&#xff0c;豐富的庫…

SQLAlchemy 常見問題筆記

文章目錄SQLAlchemy Session對象如何操作數據庫SQLAlchemy非序列化對象如何返回1.問題分析2.解決方案方法1&#xff1a;使用 Pydantic 響應模型&#xff08;推薦&#xff09;方法2&#xff1a;手動轉換為字典&#xff08;簡單快速&#xff09;方法3&#xff1a;使用 SQLAlchemy…

Shell腳本-uniq工具

一、前言在 Linux/Unix 系統中&#xff0c;uniq 是一個非常實用的文本處理命令&#xff0c;用于對重復的行進行統計、去重和篩選。它通常與 sort 搭配使用&#xff0c;以實現高效的文本數據清洗與統計分析。無論是做日志分析、訪問頻率統計&#xff0c;還是編寫自動化腳本&…

氛圍編碼(Vice Coding)的工具選擇方式

一、前言 在寫作過程中&#xff0c;我受益于若干優秀的博客分享&#xff0c;它們給予我寶貴的啟發&#xff1a; 《5分鐘選對AI編輯器&#xff0c;每天節省2小時開發時間讓你早下班&#xff01;》&#xff1a;https://mp.weixin.qq.com/s/f0Zm3uPTcNz30oxKwf1OQQ 二、AI編輯的…

[硬件電路-57]:根據電子元器件的受控程度,可以把電子元器件分為:不受控、半受控、完全受控三種大類

根據電子元器件的受控程度&#xff0c;可將其分為不受控、半受控、完全受控三大類。這種分類基于元器件的工作狀態是否需要外部信號&#xff08;如電壓、電流、光、熱等&#xff09;的主動調控&#xff0c;以及調控的精確性和靈活性。以下是具體分類及實例說明&#xff1a;一、…

基于Pytorch的人臉識別程序

人臉識別原理詳解人臉識別是模式識別和計算機視覺領域的重要研究方向&#xff0c;其目標是從圖像或視頻中識別出特定個體的身份。現代人臉識別技術主要基于深度學習方法&#xff0c;特別是卷積神經網絡 (CNN)&#xff0c;下面從多個維度詳細解析其原理&#xff1a;1. 人臉識別的…