這是我本人自己寫的一個開源庫,現已經發佈到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");
第七步 請隨意發揮~