分享
 
 
 

HTML解析类 ,让你不使用正则也能轻松获取HTML相关元素 -C# .NET

王朝学院·作者佚名  2016-05-20
窄屏简体版  字體: |||超大  

HTML解析类 ,让你不使用正则也能轻松获取HTML相关元素 -C# .NET功能:

1、轻松获取指元素HTML元素。

2、可以根据属性标签进行筛选

3、返回的都是Llist强类型无需转换

用过XElement的都知道 用来解析xml非常的方便,但是对于HTML的格式多样化实在是没办法兼容。

所以我就写了这么一个类似XElement的 XHTMLElement

用法:

string filePath = Server.MapPath("~/file/test.htm"); //获取HTML代码 string mailBody = FileHelper.FileToString(filePath); XHtmlElement xh = new XHtmlElement(mailBody); //获取body的子集a标签并且class="icon" var link = xh.Descendants("body").ChildDescendants("a").Where(c => c.Attributes.Any(a => a.Key == "class" && a.Value == "icon")).ToList(); //获取带href的a元素 var links = xh.Descendants("a").Where(c => c.Attributes.Any(a => a.Key == "href")).ToList(); foreach (var r in links) { Response.Write(r.Attributes.Single(c => c.Key == "href").Value); //出输href } //获取第一个img var img = xh.Descendants("img"); //获取最近的第一个p元素以及与他同一级的其它p元素 var ps = xh.Descendants("p");

代码:

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text;using System.Text.RegularExPRessions;namespace SyntacticSugar{ /// <summary> /// ** 描述:html解析类 /// ** 创始时间:2015-4-23 /// ** 修改时间:- /// ** 作者:sunkaixuan /// ** QQ:610262374 欢迎交流,共同提高 ,命名语法等写的不好的地方欢迎大家的给出宝贵建议 /// </summary> public class XHtmlElement { private string _html; public XHtmlElement(string html) { _html = html; } /// <summary> /// 获取最近的相同层级的HTML元素 /// </summary> /// <param name="elementName">等于null为所有元素</param> /// <returns></returns> public List<HtmlInfo> Descendants(string elementName = null) { if (_html == null) { throw new ArgumentNullException("html不能这空!"); } var allList = RootDescendants(_html); var reval = allList.Where(c => elementName == null || c.TagName.ToLower() == elementName.ToLower()).ToList(); if (reval == null || reval.Count == 0) { reval = GetDescendantsSource(allList, elementName); } return reval; } /// <summary> /// 获取第一级元素 /// </summary> /// <param name="elementName"></param> /// <returns></returns> public List<HtmlInfo> RootDescendants(string html = null) { /* * 业务逻辑: * 1、获取第一个html标签一直找结尾标签,如果在这个过程中遇到相同的标签收尾标签就要加1 * 2、第一个标签取到后继续第一步操作,找第2个元素 。。第N个元素 */ if (html == null) html = _html; var firstTag = Regex.Match(html, "<.+?>"); List<string> eleList = new List<string>(); List<HtmlInfo> reval = new List<HtmlInfo>(); GetElementsStringList(html, ref eleList); foreach (var r in eleList) { HtmlInfo data = new HtmlInfo(); data.OldFullHtml = r; data.SameLeveHtml = html; data.TagName = Regex.Match(r, @"(?<=\s{1}|\<)[a-z,A-Z]+(?=\>|\s)", RegexOptions.IgnoreCase).Value; data.InnerHtml = Regex.Match(r, @"(?<=\>).+(?=<)", RegexOptions.Singleline).Value; var eleBegin = Regex.Match(r, "<.+?>").Value; var attrList = Regex.Matches(eleBegin, @"[a-z,A-Z]+\="".+?""").Cast<Match>().Select(c => new { key = c.Value.Split('=').First(), value = c.Value.Split('=').Last().TrimEnd('"').TrimStart('"') }).ToList(); data.Attributes = new Dictionary<string, string>(); if (attrList != null && attrList.Count > 0) { foreach (var a in attrList) { data.Attributes.Add(a.key, a.value); } } reval.Add(data); } return reval; } #region private private List<HtmlInfo> GetDescendantsSource(List<HtmlInfo> allList, string elementName) { foreach (var r in allList) { if (r.InnerHtml == null || !r.InnerHtml.Contains("<")) continue; var childList = RootDescendants(r.InnerHtml).Where(c => elementName == null || c.TagName.ToLower() == elementName.ToLower()).ToList(); if (childList == null || childList.Count == 0) { childList = GetDescendantsSource(RootDescendants(r.InnerHtml), elementName); if (childList != null && childList.Count > 0) return childList; } else { return childList; } } return null; } private void GetElementsStringList(string html, ref List<string> eleList) { HtmlInfo info = new HtmlInfo(); info.TagName = Regex.Match(html, @"(?<=\<\s{0,5}|\<)([a-z,A-Z]+|h\d{1})(?=\>|\s)", RegexOptions.IgnoreCase).Value; string currentTagBeginReg = @"<\s{0,10}" + info.TagName + @".*?>";//获取当前标签元素开始标签正则 string currentTagEndReg = @"\<\/" + info.TagName + @"\>";//获取当前标签元素收尾标签正则 if (string.IsNullOrEmpty(info.TagName)) return; string eleHtml = ""; //情况1 <a/> //情况2 <a></a> //情况3 <a> 错误格式 //情况4endif if (Regex.IsMatch(html, @"<\s{0,10}" + info.TagName + "[^<].*?/>"))//单标签 { eleHtml = Regex.Match(html, @"<\s{0,10}" + info.TagName + "[^<].*?/>").Value; } else if (!Regex.IsMatch(html, currentTagEndReg))//没有收尾 { if (Regex.IsMatch(html, @"\s{0,10}\<\!\-\-\[if")) { eleHtml = GetElementString(html, @"\s{0,10}\<\!\-\-\[if", @"\[endif\]\-\-\>", 1); } else { eleHtml = Regex.Match(html, currentTagBeginReg,RegexOptions.Singleline).Value; } } else { eleHtml = GetElementString(html, currentTagBeginReg, currentTagEndReg, 1); } try { eleList.Add(eleHtml); html = html.Replace(eleHtml, ""); html = Regex.Replace(html, @"<\!DOCTYPE.*?>", ""); if (!Regex.IsMatch(html, @"^\s*$")) { GetElementsStringList(html, ref eleList); } } catch (Exception ex) { throw new Exception("SORRY,您的HTML格式不能解析!!!"); } } private string GetElementString(string html, string currentTagBeginReg, string currentTagEndReg, int i) { string newHtml = GetRegNextByNum(html, currentTagBeginReg, currentTagEndReg, i); var currentTagBeginMatches = Regex.Matches(newHtml, currentTagBeginReg, RegexOptions.Singleline).Cast<Match>().Select(c => c.Value).ToList(); var currentTagEndMatches = Regex.Matches(newHtml, currentTagEndReg).Cast<Match>().Select(c => c.Value).ToList(); if (currentTagBeginMatches.Count == currentTagEndMatches.Count) { //两个签标元素相等 return newHtml; } return GetElementString(html, currentTagBeginReg, currentTagEndReg, ++i); } private string GetRegNextByNum(string val, string currentTagBeginReg, string currentTagEndReg, int i) { return Regex.Match(val, currentTagBeginReg + @"((.*?)" + currentTagEndReg + "){" + i + "}?", RegexOptions.IgnoreCase | RegexOptions.Singleline).Value; } #endregion } public static class XHtmlElementExtendsion { /// <summa

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有