Exemplo n.º 1
0
    /// <summary>
    /// 获取当前指定书本的分析器
    /// </summary>
    BookAnalyse GetBookAnalyse(SearchCompareEventArgs e)
    {
        //k.du8.com 文章内容转好
        ListPageContentUrl url = null;

        //索引页面
        List <Skybot.Collections.Analyse.ListPageContentUrl> indexspageurl = new List <ListPageContentUrl>();

        foreach (var indexurl in e.Reslut)
        {
            bool IsBad = false;
            //查看黑名单
            foreach (var badurl in urlIndex黑名单)
            {
                if (indexurl.ToString().Contains(badurl))
                {
                    IsBad = true;
                    break;
                }
            }

            if (!IsBad)
            {
                indexspageurl.Add(indexurl);
            }
        }

        //分析内容列表的集合,的采集方式, 如果一个内容列表采集出现问题后将调用其它内容列表进行采集
        //对应列表的分析器
        //书本分析器
        List <BookAnalyseItem> BookAnalyses = new List <BookAnalyseItem>();

        //XML分析task
        List <System.Threading.Tasks.Task> xmlAnalyseTasks = new List <System.Threading.Tasks.Task>();

        foreach (var urlx in indexspageurl)
        {
            //添加到集合中
            xmlAnalyseTasks.Add(System.Threading.Tasks.Task.Factory.StartNew((o) =>
            {
                //肿可能会在获取 列表时出现错误
                try
                {
                    //单个索引页面的分析器
                    BookAnalyseItem Analyseitem = new BookAnalyseItem();

                    //运行时计算
                    ListPageContentUrl x = (ListPageContentUrl)o;

                    //取得内容页面列表
                    SingleListPageAnalyse singlelistpageAnalyse = new SingleListPageAnalyse(x.Url.ToString());
                    //最少需要有100章节才进行采集
                    if (singlelistpageAnalyse.ListPageContentUrls.Count > 100)
                    {
                        if (url == null)
                        {
                            url = x;
                        }
                        //初始化文档采集对像
                        XMLDocuentAnalyse xmlanalyse = new XMLDocuentAnalyse()
                        {
                            IndexPageUrl = x
                        };

                        //指内容页面分析器
                        Analyseitem.XMLDocuentAnalyse = xmlanalyse;
                        //指定索引页面分析器对像
                        Analyseitem.SingleListPageAnalyse = singlelistpageAnalyse;

                        //添加到分析器对像集合
                        BookAnalyses.Add(Analyseitem);

                        //初始化表达式对像
                        xmlanalyse.GetPathExpression(x, singlelistpageAnalyse.ListPageContentUrls);
                    }
                }
                catch
                {
                }
            }, urlx));
        }
        try
        {
            //等待添加页面列表分析完成 5 分钟没有完成则表示超时
            System.Threading.Tasks.Task.WaitAll(xmlAnalyseTasks.ToArray(), TimeSpan.FromMinutes(5));
        }
        catch (AggregateException ex)
        {
            ex.Handle((exx) =>
            {
                System.Diagnostics.Debug.WriteLine(exx.Message + "|||||" + exx.StackTrace);
                return(true);
            });
        }
        #region 处理结果中的异常
        //合并结果
        xmlAnalyseTasks.ForEach((xo) =>
        {
            //表示异步已经处理
            if (xo.Exception != null)
            {
                xo.Exception.Handle((ex) =>
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message + "|||||" + ex.StackTrace);
                    return(true);
                });
            }
        });
        #endregion

        #region 取得分析列表页面分析实体集合与内容页面分析实体集合结果



        //取得内容页面列表
        BookAnalyseItem DefaultAnalyse = null;
        //当前可用的章节列表
        IEnumerable <BookItem> DocumentItems = AnalyseUrlTitles(BookAnalyses);

        //清除不要的一些记录
        Func <BookItem, int> fcuc = (x) =>
        {
            var xr = x.SortTile.Split(' ');
            int n  = 0;
            if (xr.Length < 2)
            {
                return(0);
            }
            int.TryParse(xr[0], out n);
            if (n <= 0)
            {
                return(0);
            }

            if (xr[1].Trim() == "")
            {
                return(0);
            }
            return(n);
        };
        //取得章节最小值
        var rs = DocumentItems.ToLookup(p => fcuc(p));


        //输出结果
        //string resultstring = string.Join("\r\n", rs.Select(p => string.Join(" ", (from nx in p select nx.SortTile).ToArray()).ToArray()));

        #region 初始化内容列表 分析器


        //创建 一个计算 当前数据对像的集合找到
        var TempBookAnalyses = BookAnalyses.Select(p => new { count = rs.Count() - p.SingleListPageAnalyse.ListPageContentUrls.Count, item = p, exp = p.XMLDocuentAnalyse.PathExpression })
                               //进行排序找到最近的一个分析器做为最合理的分析器
                               .OrderBy(p => p.count);



        if (TempBookAnalyses.Count() > 0)
        {
            #region 这些代码已经不再使用了
            //取得内容页面列表 临时变量用于在出现找不到比它大的章节时使用
            //BookAnalyseItem TempAnalyse = null;
            ////得到当前最合理的一个采集查询分析器
            //for (int k = 0; k < TempBookAnalyses.Count(); k++)
            //{
            //    if (TempBookAnalyses.ElementAt(k).item.XMLDocuentAnalyse.PathExpression != null)
            //    {
            //        //如果当前的列表比清理过后的记录还少则先保存起来 如果后面有正数则使用正数了
            //        if (TempBookAnalyses.ElementAt(k).count <= 0)
            //        {
            //            TempAnalyse = TempBookAnalyses.ElementAt(k).item;
            //        }
            //        //如果比当前清理过的记录大
            //        else
            //        {
            //            //取值在可选范围内 不是大太多
            //            if (TempBookAnalyses.ElementAt(k).count < 60)
            //            {
            //                TempAnalyse = DefaultAnalyse = TempBookAnalyses.ElementAt(k).item;
            //                break;
            //            }
            //        }
            //    }
            //}
            ////如果实在找不到 合适的集合则使用较小的集合
            //if (DefaultAnalyse == null)
            //{
            //    DefaultAnalyse = TempAnalyse;
            //}
            #endregion

            //找到白名单中的章节列表
            for (int k = 0; k < TempBookAnalyses.Count(); k++)
            {
                if (TempBookAnalyses.ElementAt(k).item.XMLDocuentAnalyse.PathExpression != null)
                {
                    //如果当前的分析器为白名单网站  中的分析器则 提出出来做为默认分析器
                    foreach (var item in urlIndex白名单)
                    {
                        //如果当前分析器是白名单网站 则直接传值
                        if (TempBookAnalyses.ElementAt(k).item.SingleListPageAnalyse.IndexPageUrl.Contains(item))
                        {
                            DefaultAnalyse = TempBookAnalyses.ElementAt(k).item;
                        }
                    }
                }
            }

            //如果实在找不到 合适的集合则使用较大的集合
            if (DefaultAnalyse == null)
            {
                DefaultAnalyse = BookAnalyses.OrderByDescending(p => p.SingleListPageAnalyse.ListPageContentUrls.Count).FirstOrDefault();
            }
        }



        #endregion



        #endregion
        //返回分析实体结果
        return(new BookAnalyse()
        {
            BookAnalyses = BookAnalyses,
            BookAnalyseItem = DefaultAnalyse,
            VlidBookItems = DocumentItems
        });
    }
Exemplo n.º 2
0
    /// <summary>
    /// 搜索完成时输出
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void searchCompare_DoWorkAnsycComplete(object sender, SearchCompareEventArgs e)
    {
        try
        {
            //输出章节结果
            Response.Write(
                string.Join("<br/>\r\n", (from p in e.Reslut
                                          // orderby p.index
                                          select p.ToString()

                                          ).ToArray()
                            ));
            Response.Write("<br/>永生<br/>");
            //加载完成
            isCompleted = true;
        }

        //响应在这里不能用
        catch { }
        //k.du8.com 文章内容转好
        ListPageContentUrl url = null;

        //索引页面
        List <Skybot.Collections.Analyse.ListPageContentUrl> indexspageurl = new List <ListPageContentUrl>();

        foreach (var indexurl in e.Reslut)
        {
            bool IsBad = false;
            //查看黑名单
            foreach (var badurl in urlIndex黑名单)
            {
                if (indexurl.ToString().Contains(badurl))
                {
                    IsBad = true;
                    break;
                }
            }

            if (!IsBad)
            {
                indexspageurl.Add(indexurl);
            }
        }

        //分析内容列表的集合,的采集方式, 如果一个内容列表采集出现问题后将调用其它内容列表进行采集
        List <XMLDocuentAnalyse> xmlDocuentAnalyses = new List <XMLDocuentAnalyse>();
        //对应列表的分析器
        List <SingleListPageAnalyse> ingleListPageAnalyses = new List <SingleListPageAnalyse>();
        //XML分析task
        List <System.Threading.Tasks.Task> xmlAnalyseTasks = new List <System.Threading.Tasks.Task>();

        foreach (var urlx in indexspageurl)
        {
            //添加到集合中
            xmlAnalyseTasks.Add(System.Threading.Tasks.Task.Factory.StartNew((o) =>
            {
                //肿可能会在获取 列表时出现错误
                try
                {
                    //运行时计算
                    ListPageContentUrl x = (ListPageContentUrl)o;

                    //取得内容页面列表
                    SingleListPageAnalyse singlelistpageAnalyse = new SingleListPageAnalyse(x.Url.ToString());
                    //最少需要有100章节才进行采集
                    if (singlelistpageAnalyse.ListPageContentUrls.Count > 100)
                    {
                        if (url == null)
                        {
                            url = x;
                        }
                        //初始化文档采集对像
                        XMLDocuentAnalyse xmlanalyse = new XMLDocuentAnalyse()
                        {
                            IndexPageUrl = x
                        };

                        //添加到集合中
                        xmlDocuentAnalyses.Add(xmlanalyse);
                        //初始化表达式对像
                        xmlanalyse.GetPathExpression(x, singlelistpageAnalyse.ListPageContentUrls);
                        ingleListPageAnalyses.Add(singlelistpageAnalyse);
                    }
                }
                catch
                {
                }
            }, urlx));
        }
        //等待添加页面列表分析完成 3 分钟没有完成则表示超时
        System.Threading.Tasks.Task.WaitAll(xmlAnalyseTasks.ToArray(), TimeSpan.FromMinutes(5));
        #region 处理结果中的异常
        //合并结果
        xmlAnalyseTasks.ForEach((xo) =>
        {
            //表示异步已经处理
            if (xo.Exception != null)
            {
                xo.Exception.Handle((ex) =>
                {
                    System.Diagnostics.Debug.WriteLine(ex.Message + "|||||" + ex.StackTrace);
                    return(true);
                });
            }
        });
        #endregion

        //取得内容页面列表
        SingleListPageAnalyse singleListPageAnalyse = null;
        //XML分析页面
        XMLDocuentAnalyse xmlAnalyse = null;
        #region 初始化内容列表 分析器
        //得到当前最合理的一个采集查询分析器
        singleListPageAnalyse = new Func <SingleListPageAnalyse>(() =>
        {
            //用于返回的结果
            SingleListPageAnalyse resultAnalyse = null;

            //div
            var div = xmlDocuentAnalyses.Where(p => p.PathExpression.Length > 0).Where(p => p.PathExpression.Split('/').Last().Contains("div"));


            if (div.Count() > 0)
            {
                //XML分析页面
                xmlAnalyse = div.First();
                //得到查询idv的表达式的结果
                var divresults = ingleListPageAnalyses.Where(p => p.IndexPageUrl.Trim() == div.First().IndexPageUrl.Url.ToString().Trim());
                if (divresults.Count() > 0)
                {
                    resultAnalyse = divresults.First();
                }
            }
            else
            {
                //td
                var td = xmlDocuentAnalyses.Where(p => p.PathExpression.Length > 0).Where(p => p.PathExpression.Split('/').Last().Contains("td"));


                if (td.Count() > 0)
                {
                    //XML分析页面
                    xmlAnalyse = td.First();
                    //得到查询idv的表达式的结果
                    var tdresults = ingleListPageAnalyses.Where(p => p.IndexPageUrl.Trim() == div.First().IndexPageUrl.Url.ToString().Trim());
                    if (tdresults.Count() > 0)
                    {
                        resultAnalyse = tdresults.First();
                    }
                }
                else
                {
                    //li
                    var li = xmlDocuentAnalyses.Where(p => p.PathExpression.Length > 0).Where(p => p.PathExpression.Split('/').Last().Contains("li"));

                    if (li.Count() > 0)
                    {
                        //XML分析页面
                        xmlAnalyse = li.First();

                        //得到查询idv的表达式的结果
                        var liresults = ingleListPageAnalyses.Where(p => p.IndexPageUrl.Trim() == div.First().IndexPageUrl.Url.ToString().Trim());
                        if (liresults.Count() > 0)
                        {
                            resultAnalyse = liresults.First();
                        }
                    }
                }
            }



            return(resultAnalyse);
        }).Invoke();
        #endregion



        if (singleListPageAnalyse != null && xmlAnalyse != null)
        {
            //XML分析页面
            //XMLDocuentAnalyse xmlAnalyse = xmlDocuentAnalyses.Where(p => p.IndexPageUrl.ToString().Trim() == singleListPageAnalyse.IndexPageUrl.Trim()).First();
            //得到表达式
            string express = xmlAnalyse.GetPathExpression(url, singleListPageAnalyse.ListPageContentUrls);

            #region 开始写入文件
            //出错的url
            List <Skybot.Collections.Analyse.ListPageContentUrl> errurls = new List <ListPageContentUrl>();
            //开始写入文件
            //注意 写入通过正则表达式获取内容的时候可能会 获取空内容的请况,只要发现内容少于100 就可能是无效的内容需要重新获取
            singleListPageAnalyse.ListPageContentUrls.AsParallel().WithDegreeOfParallelism(20).ForAll((o) =>
            {
                try
                {
                    //处理 a标签
                    string content = ClearTags(xmlAnalyse.GetContent(o.Url.GetWeb()).Replace("<a", "\r\n<a"));

                    //如果内容无效
                    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 = ingleListPageAnalyses.Where(p => p != singleListPageAnalyse);
                        //在这些分析器中找到所有的这个章节的列表
                        var otherContentPages = from p in otherListPageAnalyse
                                                select new
                        {
                            ListPageAnalyse = p,
                            url             = ContetPageUrl(p.ListPageContentUrls, o),
                            xmlAnalyse      = xmlDocuentAnalyses.Where(xp => xp.IndexPageUrl.Url.ToString().Trim() == p.IndexPageUrl.Trim())
                        };

                        //取出文章内容
                        var ContentPagesEntity = from p in otherContentPages
                                                 where p.url != null
                                                 select new { ListPageAnalyse = p.ListPageAnalyse, url = p.url, PageContent = p.url.Url.GetWeb(), xmlAnalyse = p.xmlAnalyse.Count() > 0 ? p.xmlAnalyse.First() : null };

                        var all = ContentPagesEntity.AsParallel().ToList();

                        //制造垃圾,等系统回收
                        var allContents = all.Select(p => p.xmlAnalyse != null ? p.xmlAnalyse.GetContent(p.PageContent).Replace("<a", "\r\n<a") : p.PageContent.Replace("<a", "\r\n<a")).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 * 2000);
                                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
                    }
                    //创建目录
                    var dir = @"C:\temp\" + e.ToKen.ToString();
                    if (!System.IO.Directory.Exists(dir))
                    {
                        System.IO.Directory.CreateDirectory(dir);
                    }

                    System.IO.File.WriteAllText(dir + "\\" + FilterSpecial(o.Title).Replace("(", "").Replace(")", "").Replace("?", "").Replace("*", "").Replace(".", "").Replace("/", "").Replace("\"", "").Replace("'", "").Replace("\\", "") + ".html", content);
                }
                catch (System.Net.Sockets.SocketException)
                {
                    errurls.Add(o);
                }
            });


            #endregion


            System.Diagnostics.Debug.WriteLine("/////" + express);
        }
    }