Exemple #1
0
    /// <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);
        }
    }
Exemple #2
0
    /// <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;
        });
    }