/// <summary> /// 没有表达式 /// </summary> /// <param name="Content"></param> /// <param name="NoExpress"></param> /// <returns></returns> public string GetContentX(string Content) { //如果为 null 直接返回 if (Content == null) { return(""); } //如果没有内容 if (Content.Length < 300) { return(""); } //原素标签 var elementTags = new string[] { "p", "span", "strong", "font", "h1", "tbody", "o:p", "dd", "tr", "table" }; HtmlDocument htmlDom = new HtmlDocument(); //格式化为html htmlDom.LoadHtml(Content); //格式化为html Content = htmlDom.DocumentNode.OuterHtml; //重新加载HTML字符串 对一些标签进行闭合 //htmlDom.LoadHtml(Content.FiltrateHTML(elementTags)); htmlDom.DocumentNode.InnerHtml = string.Empty; //使用内容自动分析 XMLDocuentAnalyseEntity entity = new XMLDocuentAnalyseEntity() { BaseUrlObject = null, HtmlDocument = null, OriginContent = Content, PageTitle = "没有指定", Content = "", IsGetContentSuccess = false, IndexPageUrl = this.IndexPageUrl, XmlParseConten = "<data>" + Content + "</data>", Expression = "", }; #region 得到文档内容 // <summary> // 得到主要内容 的表达式 如果没有则返回空 // 同时填充 Content ,Expression 属性 // </summary> GetMainContentExpression(entity); entity.BaseUrlObject = null; entity.HtmlDocument = null; entity.OriginContent = null; entity.PageTitle = null; entity.IsGetContentSuccess = false; entity.IndexPageUrl = null; entity.XmlParseConten = null; entity.Expression = null; #endregion return(entity.Content); }
/// <summary> /// 得到主要内容 的表达式 如果没有则返回空 /// 同时填充 Content ,Expression 属性 /// </summary> /// 算法说明 /// 使用XMLDocument /// 1. 使用正则表达式得到所有中文集合 , 取得所有的中文一段一段的集合 /// 2. 转换成为 正则表达式 Match的集合,方便使用Linq 计算 string GetMainContentExpression(XMLDocuentAnalyseEntity domEntity) { //主要内容 string mainContont = ""; //使用正则表达式得到所有中文集合 System.Text.RegularExpressions.MatchCollection MC = System.Text.RegularExpressions.Regex.Matches(domEntity.XmlParseConten, @"[\u4e00-\u9fa5\d\w123456789~!!·#¥%……—*()——+/”》“‘’,;。、?,:…《]+[\u4e00-\u9fa5123456789~!!·#¥%……—*(!)——+/”》“‘,’\r\n;。、?,:…《]"); //取得所有的中文一段一段的集合 //转换成为 正则表达式 Match的集合 int index = 0; var matchResluts = from x in MC.Cast <System.Text.RegularExpressions.Match>() select new MatchReslut { Match = x, Index = index++, StrinLength = x.Value.Length, //与上一个表达式相隔的位置,一个 mc 一个位置记数 space = 0 } ; //得到有有效内容的集合 List <MatchReslut> ContentTempTextarr = new List <MatchReslut>(); try { //计算出 上一个表达式相隔的位置,一个 mc 一个位置记数 matchResluts.Where(p => p.StrinLength >= TextValidLength).Aggregate((curr, next) => { ContentTempTextarr.Add(new MatchReslut { Match = next.Match, Index = next.Index, StrinLength = next.StrinLength, //与上一个表达式相隔的位置,一个 mc 一个位置记数 space = Math.Abs(next.Index - curr.Index) }); return(next); }); } //序列不包含任何异常 catch { } //如果没有找到有效的内容 可能是图片/ //需要对文字内容处理后得到的表达式对这个URL进行处理 if (ContentTempTextarr.Count() == 0) { return(""); } //填充距离 位置记数后使用Xdocument来取得文章内容 //遍历有效内容集合,对 space 距离 位置记数 进行分析 如果两个 相近的原素间 space 值过大则可能是两个不同的原素了 //对结果进行用 Space分组 List <List <MatchReslut> > groupMathResult = new List <List <MatchReslut> >(); //如果超过10 则可能需要分成不同的组了 int MaxSpace = 10; //用于添加的组 List <MatchReslut> group = new List <MatchReslut>(); //添加默认组 groupMathResult.Add(group); //将可能的文字编写方式,进行分组 ContentTempTextarr.ForEach((o) => { //需要分胡重新初始化 if (o.space > MaxSpace) { group = new List <MatchReslut>(); groupMathResult.Add(group); } group.Add(o); }); //取出结果最多的那个组做为有效内容的 集合进行提取 //找到有效的原素 var ValidMathes = groupMathResult.OrderByDescending(p => p.Count).ElementAt(0); //通过有效值生成动态数表达式 List <string> regStr = new List <string>(); ValidMathes.ForEach((o) => { if (o != ValidMathes.Last()) { regStr.Add(o.Match.Value + @"[\w\W]+"); } else { regStr.Add(o.Match.Value); } }); //提取数据 mainContont = System.Text.RegularExpressions.Regex.Match(domEntity.XmlParseConten, string.Join("", regStr.ToArray())).Value; #region 开始查找包含这些内容的最内层的原素 HtmlDocument htmldom = new HtmlDocument(); htmldom.LoadHtml(domEntity.OriginContent); List <HtmlNode> htmlNodes = new List <HtmlNode>(); // 遍历所有HTML原素 EachAllHTMLElelents(htmldom.DocumentNode, htmlNodes, tong.ForMatTextReplaceHTMLTags(mainContont).Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(" ", "")); if (htmlNodes.Count > 0) { var Mainel = htmlNodes.Last(); //设置内容 domEntity.Content = Mainel.InnerHtml; //指表达式 domEntity.Expression = Mainel.XPath; //返回path表达式 return(Mainel.XPath); } return(""); #endregion }
/// <summary> /// 找到当前文章内容并填充为xdom原素 /// </summary> /// <param name="indexPageUrl"></param> /// <param name="ContentPageUrl"></param> /// <returns></returns> XMLDocuentAnalyseEntity FillContentUrl(ListPageContentUrl indexPageUrl, ListPageContentUrl ContentPageUrl) { //主要内容 string MainContent = ""; //用于保存原始内容 string originContent = ""; //得到要读取的页面 string pageurl = ContentPageUrl.Url.ToString(); //结果文档 XMLDocuentAnalyseEntity entity = null; //得到当前页面的HTML内容 string htmlContent = ""; //原素标签 var elementTags = new string[] { "p", "span", "strong", "font", "h1", "tbody", "o:p", "dd", "tr", "table" }; //基url Uri baseUri = new Uri(pageurl); #region 把文档转换成为 XDocument //得到当前页面的HTML内容 //并将HTML转换成为xml originContent = htmlContent = pageurl.GetWeb(); HtmlDocument htmlDom = new HtmlDocument(); //格式化为html htmlDom.LoadHtml(htmlContent); htmlContent = htmlDom.DocumentNode.OuterHtml; //重新加载HTML字符串 对一些标签进行闭合 htmlDom.LoadHtml(htmlContent.FiltrateHTML(elementTags)); #endregion entity = new XMLDocuentAnalyseEntity() { BaseUrlObject = ContentPageUrl, HtmlDocument = htmlDom, OriginContent = htmlContent, PageTitle = ContentPageUrl.Title, Content = MainContent, IsGetContentSuccess = MainContent.Length > 50 ? true : false, IndexPageUrl = indexPageUrl, XmlParseConten = "<data>" + htmlContent + "</data>", Expression = "", }; #region 得到文档内容 GetMainContentExpression(entity); #endregion //重新设置加载状态 entity.IsGetContentSuccess = MainContent.Length > 50 ? true : false; //返回结果 return(entity); }
/// <summary> /// 得到主要内容 的表达式 如果没有则返回空 /// 同时填充 Content ,Expression 属性 /// </summary> /// 算法说明 /// 使用XMLDocument /// 1. 使用正则表达式得到所有中文集合 , 取得所有的中文一段一段的集合 /// 2. 转换成为 正则表达式 Match的集合,方便使用Linq 计算 string GetMainContentExpression(XMLDocuentAnalyseEntity domEntity) { //主要内容 string mainContont = ""; //使用正则表达式得到所有中文集合 System.Text.RegularExpressions.MatchCollection MC = System.Text.RegularExpressions.Regex.Matches(domEntity.XmlParseConten, @"[\u4e00-\u9fa5\d\w123456789~!!·#¥%……—*()——+/”》“‘’,;。、?,:…《]+[\u4e00-\u9fa5123456789~!!·#¥%……—*(!)——+/”》“‘,’\r\n;。、?,:…《]"); //取得所有的中文一段一段的集合 //转换成为 正则表达式 Match的集合 int index = 0; var matchResluts = from x in MC.Cast <System.Text.RegularExpressions.Match>() select new MatchReslut { Match = x, Index = index++, StrinLength = x.Value.Length, //与上一个表达式相隔的位置,一个 mc 一个位置记数 space = 0 } ; //得到有有效内容的集合 List <MatchReslut> ContentTempTextarr = new List <MatchReslut>(); if (MC.Count > 0) { try { //计算出 上一个表达式相隔的位置,一个 mc 一个位置记数 var list = matchResluts.Where(p => p.StrinLength >= TextValidLength); if (list.Count() > 0) { list.Aggregate((curr, next) => { ContentTempTextarr.Add(new MatchReslut { Match = next.Match, Index = next.Index, StrinLength = next.StrinLength, //与上一个表达式相隔的位置,一个 mc 一个位置记数 space = Math.Abs(next.Index - curr.Index) }); return(next); }); } } //序列不包含任何异常 catch (Exception ex) { System.Diagnostics.Debug.WriteLine(DateTime.Now + ex.Message + "|||||" + ex.StackTrace); } } //如果没有找到有效的内容 可能是图片/ //需要对文字内容处理后得到的表达式对这个URL进行处理 if (ContentTempTextarr.Count == 0) { return(""); } //填充距离 位置记数后使用Xdocument来取得文章内容 //遍历有效内容集合,对 space 距离 位置记数 进行分析 如果两个 相近的原素间 space 值过大则可能是两个不同的原素了 //对结果进行用 Space分组 List <List <MatchReslut> > groupMathResult = new List <List <MatchReslut> >(); //如果超过10 则可能需要分成不同的组了 int MaxSpace = 10; //用于添加的组 List <MatchReslut> group = new List <MatchReslut>(); //添加默认组 groupMathResult.Add(group); //将可能的文字编写方式,进行分组 ContentTempTextarr.ForEach((o) => { //需要分胡重新初始化 if (o.space > MaxSpace) { group = new List <MatchReslut>(); groupMathResult.Add(group); } group.Add(o); }); //取出结果最多的那个组做为有效内容的 集合进行提取 //找到有效的原素 var ValidMathes = groupMathResult.OrderByDescending(p => p.Count).ElementAt(0); //通过有效值生成动态数表达式 List <string> regStr = new List <string>(); ValidMathes.ForEach((o) => { if (o != ValidMathes.Last()) { regStr.Add(o.Match.Value + @"[\w\W]+"); } else { regStr.Add(o.Match.Value); } }); //提取数据 //mainContont = System.Text.RegularExpressions.Regex.Match(domEntity.XmlParseConten, string.Join("", regStr.ToArray())).Value; #region 正则表达式线程CPU 100% 优化方法 //放在一个线程里,如果超过3秒线程还没有执行完成则直接关闭线程 //这样可以保证CPU100%的情况得到改善 System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(() => { try { //提取数据 mainContont = System.Text.RegularExpressions.Regex.Match(domEntity.XmlParseConten, string.Join("", regStr.ToArray())).Value; } catch (OutOfMemoryException ex) { System.Diagnostics.Debug.WriteLine(DateTime.Now + "提取数据" + ex.Message + "|||||" + ex.StackTrace); } })); thread.Start(); //task只是做一个等待器 System.Threading.Tasks.Task task = new System.Threading.Tasks.Task(() => { }); //如果3秒还没有分析出来正则表达式结果 if (!task.Wait(1000 * 3) && string.IsNullOrEmpty(mainContont)) { thread.Abort(); return(mainContont); } #endregion #region 开始查找包含这些内容的最内层的原素 HtmlDocument htmldom = new HtmlDocument(); htmldom.LoadHtml(domEntity.OriginContent); List <HtmlNode> htmlNodes = new List <HtmlNode>(); // 遍历所有HTML原素 EachAllHTMLElelents(htmldom.DocumentNode, htmlNodes, tong.ForMatTextReplaceHTMLTags(mainContont).Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(" ", "")); if (htmlNodes.Count > 0) { var Mainel = htmlNodes.Last(); //设置内容 domEntity.Content = Mainel.InnerHtml; //指表达式 domEntity.Expression = Mainel.XPath; //清空变量 htmlNodes.Clear(); htmldom.DocumentNode.InnerHtml = string.Empty; //返回path表达式 return(Mainel.XPath); } //清空变量 htmlNodes.Clear(); htmldom.DocumentNode.InnerHtml = string.Empty; return(""); #endregion }
/// <summary> /// 找到当前文章内容并填充为xdom原素 /// </summary> /// <param name="indexPageUrl"></param> /// <param name="ContentPageUrl"></param> /// <returns></returns> XMLDocuentAnalyseEntity FillContentUrl(ListPageContentUrl indexPageUrl, ListPageContentUrl ContentPageUrl) { //主要内容 string MainContent = ""; //用于保存原始内容 string originContent = ""; //得到要读取的页面 string pageurl = ContentPageUrl.Url.ToString(); //结果文档 XMLDocuentAnalyseEntity entity = null; //得到当前页面的HTML内容 string htmlContent = ""; //原素标签 var elementTags = new string[] { "p", "span", "strong", "font", "h1", "tbody", "o:p", "dd", "tr", "table" }; //基url Uri baseUri = new Uri(pageurl); #region 把文档转换成为 XDocument //得到当前页面的HTML内容 //并将HTML转换成为xml originContent = htmlContent = pageurl.GetWeb(); HtmlDocument htmlDom = new HtmlDocument(); //格式化为html htmlDom.LoadHtml(htmlContent); //有些文章会出现 无限循环异常 //try //{ htmlContent = htmlDom.DocumentNode.OuterHtml; //重新加载HTML字符串 对一些标签进行闭合 htmlDom.LoadHtml(htmlContent.FiltrateHTML(elementTags)); //} //catch (OverflowException ex) //{ // System.Diagnostics.Debug.WriteLine(DateTime.Now + ex.Message + "|||||" + ex.StackTrace); // return new XMLDocuentAnalyseEntity() // { // BaseUrlObject = ContentPageUrl, // HtmlDocument = htmlDom, // OriginContent = htmlContent, // PageTitle = ContentPageUrl.Title, // Content = MainContent, // IsGetContentSuccess = MainContent.Length > 50 ? true : false, // IndexPageUrl = indexPageUrl, // XmlParseConten = "<data>" + htmlContent + "</data>", // Expression = "", // }; //} #endregion entity = new XMLDocuentAnalyseEntity() { BaseUrlObject = ContentPageUrl, HtmlDocument = htmlDom, OriginContent = htmlContent, PageTitle = ContentPageUrl.Title, Content = MainContent, IsGetContentSuccess = MainContent.Length > 50 ? true : false, IndexPageUrl = indexPageUrl, XmlParseConten = "<data>" + htmlContent + "</data>", Expression = "", }; #region 得到文档内容 GetMainContentExpression(entity); #endregion //重新设置加载状态 entity.IsGetContentSuccess = MainContent.Length > 50 ? true : false; //返回结果 return(entity); }