以對象的方式訪問html中的標簽,比正則表達式更好用的方式獲取html中的內容,linq方式直接獲取所有的鏈接,更加先進的c#版本爬蟲開源庫

来源:https://www.cnblogs.com/zhaimaojun/p/18074346/htmlparser
-Advertisement-
Play Games

這是我本人自己寫的一個開源庫,現已經發佈到nuget,可以直接在vs的nuget包管理中搜索到,或者可以到nuget官網下載:https://www.nuget.org/packages/ZmjConvert/,也可以到我的個人網站上下載源碼:https://www.zhaimaojun.cn/P/ ...


這是我本人自己寫的一個開源庫,現已經發佈到nuget,可以直接在vs的nuget包管理中搜索到,或者可以到nuget官網下載:https://www.nuget.org/packages/ZmjConvert/,也可以到我的個人網站上下載源碼:https://www.zhaimaojun.cn/P/C%23%e6%a0%87%e7%ad%be%e7%b1%bb%e6%96%87%e6%9c%ac%e5%ba%8f%e5%88%97%e5%8c%96%e5%ba%93/

本包是.NET standard標準庫包,可以在.NET core,.NET,.NET framework等多種項目中直接使用,我本人也是在多種環境中使用這個包,沒有任何問題的,我本人主要用來提取網頁上的鏈接,圖片,可顯示文本等內容。

先安裝這個包,然後就可以使用了,下麵給出了一些使用方式的模板:

第一步 序列化html

/**這是html源碼的序列化*/
1
var dts = GetSource();//獲取html源碼,可以現下或者讀取html文件,dts需要是string類型的html內容 2 if (!HtmlElement.TryParse(dts, out var eles, out var err)) 3 { 4 OnDownloadErrorHappend($"無法序列化url:{surl}");//反序列化失敗 5 return; 6 } 7 var srcurl = new Uri(surl);//這是html的源地址的當前文檔的url,用於將當前所有節點中相對路徑解析為絕對路徑時使用 8 eles = HtmlElement.GetAllElement(eles);//列出所有的子元素,就是將所有的節點提取為一個list,方便使用linq,或者使用foreach迴圈來遍歷,當然原來的標簽結構是不會改變的。
 1 /**這是部分html標簽源碼的反序列化,比如富文本編輯器的內容*/
 2 try
 3 {
 4     var labstr = Gethtmlstr();//獲取部分標簽的html源碼,比如富文本編輯器
 5     var eles = CHtmlElement<HtmlElement>.Parse(htmlstr);//反序列化標簽組
 6     return eles;//反序列化成功後返回結構對象
 7 }
 8 catch (Exception e)
 9 {
10     throw e;//反序列化失敗
11 }

第二步 獲取html文檔的標題

1 var title = HtmlElement.GetWebTitle(eles);
1 /**獲取文檔的keywords*/
2 eles.FirstOrDefault(x => x.TagName == "meta" && x.Attributes.ContainsKey("name") && x.Attributes["name"].ToLower() == "keywords").Attributes.TryGetValue("content", out var keywords);
3 /**獲取文檔的description*/
4 eles.FirstOrDefault(x => x.TagName == "meta" && x.Attributes.ContainsKey("name") && x.Attributes["name"].ToLower() == "description").Attributes.TryGetValue("content", out var description);

第三步 提取所有的img標簽的src,也就是獲取所有頁面上的圖片

1 /**這是獲取所有img標簽的src屬性內容*/
2 var imgs = new List<string>();
3 foreach (var e in eles.Where(x => x.TagName == "img" && x.Attributes.ContainsKey("src") && !string.IsNullOrWhiteSpace(x.Attributes["src"])))
4 {//封面圖片或者其他圖片
5     var furl = HttpUtility.HtmlDecode(e.Attributes["src"]);
6     var furi = new Uri(srcurl, furl);
7     imgs.Add(furi.AbsoluteUri);
8 }
/**這是提取所有img標簽的data-src屬性,因為有些網站為了降低流量成本,img標簽的src屬性中使用的是縮略圖,而data-src中使用的才是原圖*/
1
var imgs = new List<string>(); 2 foreach (var e in eles.Where(x => x.TagName == "img" && x.Attributes.ContainsKey("data-src") && !string.IsNullOrWhiteSpace(x.Attributes["data-src"]))) 3 {//封面圖片或者其他圖片 4 var furl = HttpUtility.HtmlDecode(e.Attributes["data-src"]); 5 var furi = new Uri(srcurl, furl); 6 imgs.Add(furi.AbsoluteUri); 7 }

第四步 提取所有的a標簽的href,也就是獲取所有頁面上的鏈接

1 /**獲取所有的鏈接及鏈接的文本內容*/
2 var links = new Dictionary<string, string>();
3 foreach (var e in eles.Where(x => x.TagName == "a" && x.Attributes.ContainsKey("href") && !string.IsNullOrWhiteSpace(x.Attributes["href"])))
4 {
5     links.Add(WebUtility.HtmlDecode(e.InnerText), WebUtility.HtmlDecode(e.Attributes["href"]));
6 }

第五步 提取所有可視文本,並保持換行,並且保持鏈接的有效

 1 /**提取所有的可視文本*/
 2 var tsts = new List<string>();//這是按行存儲的提取到的所有可視內容
 3 var sb = new StringBuilder();//這是中間使用的拼接對象
 4 foreach (var item in eles)//eles為整個html反序列化後的列表,如果需要對指定的一個div或者p的可視內容提取,可以先找到這個標簽對象,然後在通過HtmlElement.GetAllElement(e.Children)可提取他的所有子標簽,就可以提取所有可視內容了
 5 {
 6     var tgs = new[] { "br", "div", "li", };//這是強迫換行的標簽列舉,可根據需求添加或減少
 7     if (tgs.Contains(item.TagName))
 8     {
 9         sb.Append(HttpUtility.HtmlDecode(item.InnerText));
10         var innt = sb.ToString();
11         tsts.Add(innt);
12         sb.Clear();
13     }
14     else if (item.TagName == "a" && item.Attributes.ContainsKey("href") && !item.Attributes["href"].Contains("f95")) sb.Append($"<a href=\"{WebUtility.HtmlDecode(item.Attributes["href"])}\">{WebUtility.HtmlDecode(item.InnerText)}</a>");
15     else if (!item.InnerText.Contains('<')) sb.Append(HttpUtility.HtmlDecode(item.InnerText));
16 }

第六步 找到特定的標簽

1 /**查找包含main-content樣式類的div*/
2 var e = eles.FirstOrDefault(x => x.TagName == "div" && x.Attributes.ContainsKey("class") && x.Attributes["class"].ToLower().Contains("main-content"));
/**查找id為mainp的p標簽*/
var e = eles.FirstOrDefault(x => x.TagName == "p" && x.Attributes.ContainsKey("id") && x.Attributes["id"].ToLower() == "mainp");

第七步 請隨意發揮~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • roncoo-education —— 一個分散式線上教育系統。目前主要功能有課程點播功能,支持多家視頻雲的接入,課程附件管理功能,支持多家存儲雲的接入,可以幫助個人或者企業快速搭建一個輕量級的線上教育平臺。 ...
  • 在Java多線程編程中,正確且安全地停止線程是一項關鍵技能。簡單粗暴地“殺死”線程不僅可能導致數據不一致性,還可能引發各種難以預測的錯誤。 ...
  • 這個作業屬於哪個課程 軟體工程2024 這個作業要求在哪裡 個人項目 這個作業的目標 瞭解軟體項目開發的整體流程,實現自己的個人項目,學習單元測試、性能優化和 git 操作,學會使用 PSP 表格 Github地址 : 點擊此處,進入我的倉庫 一、項目需求 題目:論文查重 設計一個論文查重演算法,給出 ...
  • 大家好,我是R哥。 周末愉快呀,最近我在做 Java 面試輔導,也模擬面試了好些個學員,說說其中一個學員吧,一個工作 5 年的 Java 程式員,模擬面試,居然一個問題也不會。。 當晚模擬面試完,我的心情很複雜。 我之前做系統架構師,同時也是面試官,這些年,少說也面試過幾百上千人,不乏知識淵博、技能 ...
  • .NET 6 引入了 LoggerMessageAttribute 類型。 使用時,它會以source-generators的方式生成高性能的日誌記錄 API。 source-generators可在編譯代碼時,可以提供其他源代碼作為編譯的輸入。 LoggerMessageAttribute依賴於 ...
  • 概述:ValueStopwatch是.NET中輕量級計時器,用於高性能時間測量。作為值類型,避免了裝箱拆箱開銷,記憶體占用小。通過簡單的使用方法,輕鬆實現代碼塊執行時間測量,且相比Stopwatch更為高效。 在.NET中,ValueStopwatch是一個輕量級的計時器類,用於測量代碼塊的執行時間。 ...
  • 概述:`Directory.Packages.props`和`Directory.Build.props`是.NET項目中的配置文件,分別用於統一管理NuGet包引用和自定義MSBuild構建過程。它們提高瞭解決方案的可維護性,通過集中配置,簡化了項目文件,使團隊協作更一致,同時避免了在每個項目中重 ...
  • 示例項目:https://gitee.com/easyxaf/recharge-rules-engine-sample 前言 繼上一篇文章對規則引擎編輯器進行了初步介紹之後,本文將通過實際應用案例深入探討規則引擎編輯器的使用方法。編輯器的操作相對簡單,我們將重點放在RulesEngine的講解上。請 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...