本帖最后由 prestashop 于 2011-08-21 14:57:25 编辑

解决方案 »

  1.   

    是通过 多线程现抓的,先通过程序用多线程提取一批网址,通过网址获取源码,通过源码提取邮箱。以上两段代码 同处一个程序里,都被多线程调用,先调用提取源码代码,紧接着调用提取邮箱源码。两段代码是挨在一起的,但是占用CPU资源却一天一地。
      

  2.   

    正则表达式让CPU100%很正常抓取是不怎么耗CPU的,因为他基本上是在等待回应我觉得你可以开两个线程来做这个事情
    让抓取的同时能够对数据处理只开一个处理的线程就够了,若果是多核的就多开几个总之,正则表达式处理大量数据时占用CPU很多是很正常的
      

  3.   


    说的也是,但终究不是办法,如果一个程序只能开一两个线程,那吸引力会大打折扣。但是 你能解释下为什么两段几乎相同的代码,占用CPU资源却相差90% 左右呢?我保证两段代码除了正则表达式不一样之外,其它都相同。
      

  4.   

    你提取Email慢很多是因为你使用RegexOptions.IgnoreCase.
    另外使用RegexOptions.Compiled会有一定作用            static Regex regexLink = new Regex(@"(href|HREF)[ ]*=[ ]*[""'][^""'#>]+[""']", RegexOptions.Compiled);
                static Regex regexEmail = new Regex(@"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}", RegexOptions.Compiled);
                public static string[] ExtractLinks(string html) {
                    Collection<string> urls = new Collection<string>();
                    try {
                        MatchCollection matches = regexLink.Matches(html);
                        string str = null;
                        foreach (Match match in matches) {
                            str = match.Value;
                            urls.Add(str);
                        }
                    } catch (Exception ex) {
                        Console.WriteLine(ex.Message);
                    }                return urls.ToArray();
                }
                public static string[] ExtractEmails(string html) {
                    Collection<string> emails = new Collection<string>();
                    try {
                        string str = null;
                        MatchCollection matches = regexEmail.Matches(html);
                        foreach (Match match in matches) {
                            str = match.Value;
                            emails.Add(str);
                            Thread.Sleep(1);
                        }
                    } catch (Exception ex) {
                        Console.WriteLine(ex.Message);
                    }
                    return emails.ToArray();
                }
      

  5.   


    谢谢,照你说的试了,但似乎没有效果把 RegexOptions.Compiled  和 RegexOptions.IgnoreCase 都去掉,也没有降低CPU资源,两段代码只有正则表达式不同,那应该是表达式写的好坏影响了CPU资源?在程序里我如果只保留上面的第一段代码,去掉第二段代码,CPU资源占用在10%之内
      

  6.   

    谢谢,这里有个贴子,同样的问题,但是解决了http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/3f4390ac-11eb-4d67-b946-a73ffb51e4f3我看不太懂
      

  7.   

    他那个和你的不一样,你这个不涉及那么复杂的问题你的两个匹配函数中,抽取Email的肯定耗时多
    因为抽取Link的那个正则里href|Href这个条件太强了,这样可以直接跳过很多字符
    而Email中的[A-Za-z0-9]+就相对很弱了,正则引擎会进行很多尝试不过我这边的测试也只是慢了一半而已
      

  8.   

    string str = @"(href|HREF)[ ]*=[ ]*[""'][^""'#>]+[""']";
    string str = @"[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}";
    两个正则抓取的内容不一样,怎么有可比性。第一个范围比较小,会检测你的href有没有匹配成功,没有匹配成功就匹配失败。
    而第二个正则会[A-Z0-9._%+-]这个范围可就广了,一个网页内容大部分都会匹配到,然后在继续去匹配接下去的。
      

  9.   

    我用的是多线程提取邮箱,一次开25-30个线程,有时候会更多,几十个线程不间断调用正则,因此0.4秒的差距也会造成占用大量的CPU吧,是不是这样?
      

  10.   

    其实我感觉是这样的:
    如果匹配速度比抓取速度快,那么CPU利用率就很低
    如果比配速度比抓取速度慢,那CPU可能就很吃力了
      

  11.   


    你可以先用 string.IndexOf 查询所有的 “@”,然后依次仅仅取出前后30个字节来这时候才用正则。正则是一个编程小技术,它是最慢速的字符串处理,不要当作拿来就套用的东西。