/// <summary> /// 获取内容 /// </summary> /// <param name="bookAnalyse">书分析器</param> /// <param name="state">状态对像</param> void GetContents(BookAnalyse bookAnalyse, BookCollectState state) { //处理名称的方法 Func <string, string> fun = (str) => { return(string.Join("", System.Text.RegularExpressions.Regex.Matches(str, @"[\u4e00-\u9fa5\d|a-z]{1,}", System.Text.RegularExpressions.RegexOptions.Multiline) .Cast <System.Text.RegularExpressions.Match>().Select(p => p.Value).ToArray() )); }; //取得内容页面列表 SingleListPageAnalyse singleListPageAnalyse = bookAnalyse.BookAnalyseItem.SingleListPageAnalyse; //XML分析页面 XMLDocuentAnalyse xmlAnalyse = bookAnalyse.BookAnalyseItem.XMLDocuentAnalyse; if (singleListPageAnalyse != null && xmlAnalyse != null) { //得到表达式 string express = xmlAnalyse.PathExpression; #region 开始得到单个的页面内容 //开始写入文件 //注意 写入通过正则表达式获取内容的时候可能会 获取空内容的请况,只要发现内容少于100 就可能是无效的内容需要重新获取 singleListPageAnalyse.ListPageContentUrls.AsParallel().WithDegreeOfParallelism(20).ForAll((o) => { // var o = oxurlEntity.Entity.ElementAt(0).PageContentUrl; //处理 内容 string content = ""; try { //处理 a标签 content = ClearTags(xmlAnalyse.GetContent(o.Url.GetWeb()).Replace("<a", "\r\n<a")); } catch (Exception ex) { //添加出错的url state.ErrUrls.Add(o); } try { //目录 string dir = @"C:\temp\" + BookName.Text.ToString(); //写入文件 //WirtePageFile(dir, content, o); try { //如果内容无效 if (content.Length <= 200 || //中文小于6 string.Join("", System.Text.RegularExpressions.Regex.Matches(content, @"[\u4e00-\u9fa5\d\w123456789~!!·#¥%……—*()——+/”》“‘’,;。、?,:…《]+[\u4e00-\u9fa5123456789~!!·#¥%……—*(!)——+/”》“‘,’\r\n;。、?,:…《]", System.Text.RegularExpressions.RegexOptions.Multiline) .Cast <System.Text.RegularExpressions.Match>().Select(p => p.Value).ToArray() ).Length < 6 ) { #region 使用从其它文章列表中提取数据 //算法说明 //1.找到当前要查看的章节名, //2.将当前所有列表中的这个章节都取出来合并成为一个新 的类 包含分析用的XMLdom分析器与当前需要采集的url //3.取出内容, //4.对内容进行分析.最合理的那个内容做为结果,合理为,字数与其它结果的字数比较相近.不是最大也不是最小的 //其它索引页面分析器 var otherListPageAnalyse = bookAnalyse.BookAnalyses.Where(p => p.SingleListPageAnalyse != singleListPageAnalyse); //在这些分析器中找到所有的这个章节的列表 老方法 已经不再使用了因为 名称不对 var otherContentPages = from p in otherListPageAnalyse select new BookItemPage { ListPageAnalyse = p.SingleListPageAnalyse, url = ContetPageUrl(p.SingleListPageAnalyse.ListPageContentUrls, o), xmlAnalyse = p.XMLDocuentAnalyse }; // 得到这个章节的其它索引分析器的列表集合 var bookItemEntity = bookAnalyse.VlidBookItems.Where(p => p.SortTile == Filter(fun(o.Title))); //如果存在集合 if (bookItemEntity.Count() > 0) { //重新获取章节列表 otherContentPages = from p in bookItemEntity.FirstOrDefault().Entity select new BookItemPage { ListPageAnalyse = p.AnalyseEntity.SingleListPageAnalyse, url = p.PageContentUrl, xmlAnalyse = p.AnalyseEntity.XMLDocuentAnalyse }; } //取出文章内容 var ContentPagesEntity = from p in otherContentPages where p.url != null select new { ListPageAnalyse = p.ListPageAnalyse, url = p.url, //有可能读取内容的时候出现问题 PageContent = new Func <string>(() => { try { return(p.url.Url.GetWeb()); } catch { return(""); } }).Invoke(), xmlAnalyse = p.xmlAnalyse }; var all = ContentPagesEntity.AsParallel().ToList(); //制造垃圾,等系统回收 得到文章的内容 var allContents = all.Select(p => new Func <string>(() => { try { return(p.xmlAnalyse != null ? p.xmlAnalyse.GetContent(p.PageContent).Replace("<a", "\r\n<a") : p.PageContent.Replace("<a", "\r\n<a")); } catch { return(""); } }).Invoke() ).ToList(); //得到筛选的内容, 制造垃圾,等系统回收 var resultContents = allContents.Select(p => ClearTags(p)).OrderBy(p => p.Length); if (resultContents.Count() > 0) { content = resultContents.Last(); //替換掉一部分 a 标签 foreach (System.Text.RegularExpressions.Match item in System.Text.RegularExpressions.Regex.Matches(content, @"<a[^>\s\w=/]*>.*<\/a>" , System.Text.RegularExpressions.RegexOptions.None | System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)) { content = content.Replace(item.Value, ""); } } #endregion //如果内容无效的话还是用这个 if (content.Length < 100) { //启用百度搜索 BaiduSearchCompare baiduSearch = new BaiduSearchCompare(); baiduSearch.KeyWord = o.Title; //搜索 内容页面 url // e.ToKen = 永生 List <Skybot.Collections.Analyse.ListPageContentUrl> contentUrls = baiduSearch.AnalyseListUrls( string.Format(BaiduSearchCompare.BaduUrl, System.Web.HttpUtility.UrlEncode(o.Title), "").GetWeb() , false); ////////搜索章节名称时需要注意 看看能不能优化 //可能是搜索引擎出错了,如果出现了过60秒再试一下 if (contentUrls.Count == 0 && baiduSearch.KeyWord.Contains("章")) { System.Threading.Thread.Sleep(60 * 1000); contentUrls = baiduSearch.AnalyseListUrls( string.Format(BaiduSearchCompare.BaduUrl, System.Web.HttpUtility.UrlEncode(o.Title), "").GetWeb() , false); } #region 并行计算出当前页面的内容 //返回的列表结果 List <string> result = new List <string>(); //使用多线程调用搜索引擎 System.Threading.Tasks.Task[] tasks = new System.Threading.Tasks.Task[contentUrls.Count()]; #region 开始调用搜索引擎 for (int k = 0; k < tasks.Length; k++) { //初始化搜索线程并开始搜索 tasks[k] = System.Threading.Tasks.Task.Factory.StartNew <string>((contentPageurl) => { string PageHtml = contentPageurl.ToString().GetWeb(); //替換掉一部分腳本 foreach (System.Text.RegularExpressions.Match item in System.Text.RegularExpressions.Regex.Matches(PageHtml, @"<script[^>\s\w=/]*>.*<\/script>" , System.Text.RegularExpressions.RegexOptions.None | System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)) { PageHtml = PageHtml.Replace(item.Value, ""); } return(xmlAnalyse.GetContentX(PageHtml)); }, contentUrls[k].Url); } try { //等待搜索全部完成 //2分钟内全部要搜索完成如果不完成则退出 System.Threading.Tasks.Task.WaitAll(tasks, TimeSpan.FromMinutes(2)); } #region 处理异常 catch (AggregateException ex) { ex.Handle((exp) => { return(true); }); } #endregion //合并结果 tasks.ToList().ForEach((xo) => { if (xo.IsCompleted) { //添加到结果中 result.Add(ClearTags(tong.ForMatTextReplaceHTMLTags((xo as System.Threading.Tasks.Task <string>).Result.Replace("<br/>", "\r")).Replace("\r", "<br/>"))); } //表示异步已经处理 if (xo.Exception != null) { xo.Exception.Handle((ex) => { System.Diagnostics.Debug.WriteLine(ex.Message + "|||||" + ex.StackTrace); return(true); }); } }); #endregion //对搜索到的进行分析 //找出合适的内容数据 var reslutOrder = result.OrderBy(p => p.Length).Where(p => p.Length > 500).ToList(); var reqs = reslutOrder.ToList(); reqs.Clear(); //去掉nbsp 之类的空格 还有HTML标签等 如果开头是中文则表示有效的数据 reslutOrder.ForEach((p) => { //替換掉一部分 a 标签 foreach (System.Text.RegularExpressions.Match item in System.Text.RegularExpressions.Regex.Matches(p, @"<a[^>\s\w=/]*>.*<\/a>" , System.Text.RegularExpressions.RegexOptions.None | System.Text.RegularExpressions.RegexOptions.IgnoreCase | System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace)) { p = p.Replace(item.Value, ""); } //看看第几个字母是中文,数字越小越好 int Charindex = 99999; for (int n = 0; n < p.Length; n++) { var mc = System.Text.RegularExpressions.Regex.IsMatch( "" + p[n], @"[\u4e00-\u9fa5\d\w123456789~!!·#¥%……—*()——+/”》“‘’,;。、?,:…《]" ); if (mc) { Charindex = n; break; } } reqs.Add("<字符" + Charindex + "开始位置/>" + p.Replace(" ", "") .Replace(" ", "") .Replace("<br/>", "br/") .Replace("<br>", "br/") .Replace("\t", "") .Replace(" ", "") .Replace(" ", "") ); }); reslutOrder = reqs.OrderBy(p => int.Parse(System.Text.RegularExpressions.Regex.Match(p, @"^<字符\d{1,}开始位置/>").Value.Replace("<字符", "").Replace("开始位置/>", ""))).ToList(); //找到 字数最少的 的那个结果 //正文一般都会超过500个字符的 foreach (var str in reslutOrder) { if (!str.Contains("if")) { content = System.Text.RegularExpressions.Regex.Replace(str, @"^<字符\d{1,}开始位置/>", "").Replace("br/", "<br>"); //如果换行少了 if (System.Text.RegularExpressions.Regex.Matches(content, @"<br/>").Count <= 5) { content = content.Replace("”", "”<br/>"); } break; } } #endregion } } } catch (Exception ex) { //添加出错的url state.ErrUrls.Add(o); } //写入文件 如果文件不对则重新写入 WirtePageFile(dir, content, o); state.CurrentNumeric = state.CurrentNumeric + 1; //更新目录完成状态列表 //这里不改变目录集合不需要用到锁 if (state.UrlList.ContainsKey(o.Url.ToString())) { state.UrlList[o.Url.ToString()].ResultUrl = new Uri(dir + "\\" + FilterSpecial(o.Title).Replace("(", "").Replace(")", "").Replace("?", "").Replace("*", "").Replace(".", "").Replace("/", "").Replace("\"", "").Replace("'", "").Replace("\\", "") + ".html"); } } catch (Exception ex) { //添加出错的url state.ErrUrls.Add(o); } }); #endregion //指定完成 state.Count = singleListPageAnalyse.ListPageContentUrls.Count; System.Diagnostics.Debug.WriteLine("/////" + express); } }
/// <summary> /// 运行查看文章内容 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected void Unnamed1_Click(object sender, EventArgs e) { if (BookName.Text == "") { return; } //添加一个新的文章状态管理 BookCollectState state = null; var resultxd = from p in BookCollectStates where p.BookName == BookName.Text select p; //如果有这本书的记录 if (resultxd.Count() > 0) { stateText.Text = "《" + BookName.Text + "》的任务正在进行 ..."; return; } BookName.Enabled = false; ///初始化状态 state = new BookCollectState() { BookName = BookName.Text, }; //添加到记录中 BookCollectStates.Add(state); stateText.Text = "正在获取" + BookName.Text + "的信息..."; System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Factory.StartNew(() => { //得到所在页面的列表 // List<ListPageContentUrl> listPages = baiduSearch.DoWork(BookName.Text); List <ListPageContentUrl> listPages = bingsearch.DoWork(BookName.Text); //调用显示数据 得到分析结果 BookAnalyse result = GetBookAnalyse(new SearchCompareEventArgs() { Reslut = listPages, ToKen = BookName.Text }); state.BookAnalyse = result; state.Count = result.BookAnalyseItem.SingleListPageAnalyse.ListPageContentUrls.Count; state.CurrentNumeric = 0; state.Completed += new System.ComponentModel.RunWorkerCompletedEventHandler(state_Completed); var urls = (from p in result.BookAnalyseItem.SingleListPageAnalyse.ListPageContentUrls select new HrefEntity() { OriginUrl = p, }); Dictionary <string, HrefEntity> hrefs = new Dictionary <string, HrefEntity>(); foreach (var ur in urls) { hrefs[ur.OriginUrl.ToString()] = ur; } //初始化目录URL state.UrlList = hrefs; //将获取的书写入内容 GetContents(result, state); }); //这样就不会出现页面阻塞了 System.Threading.Tasks.Task.Factory.StartNew(() => { try { //等待添任务执行完成 task.Wait(); } catch (AggregateException ex) { ex.Handle((exx) => { System.Diagnostics.Debug.WriteLine(exx.Message + "|||||" + exx.StackTrace); return(true); }); ex.Flatten().Handle((exx) => { System.Diagnostics.Debug.WriteLine(exx.Message + "|||||" + exx.StackTrace); return(true); }); } BookName.Enabled = true; }); }