2013-01-17 67 views
0

所以我需要保存一個站點的多個鏈接,但是當它到達64k鏈接附近時,它會給我錯誤OutOfMemoryExceptionWebCrawler中的OutOfMemoryException

這是我的代碼,如果有人能幫助我,這將是美好的。

注意:如果你想測試(當然,你必須編輯測試,但它不是那麼多編輯),它收到的網址是:

http://santacatarina.entrei.net/busca/listar_empresas.php?filter={0}&pagina={1} 

代碼:

namespace WebCrawler.SantaCatarina 
{ 

class SCLinkFinder : ILinkFinder 

{ 

private readonly Queue<char> _alfabeto; 
private int _paginaAtual; 
private char _letraAtual; 

public SCLinkFinder() 
{ 
    _alfabeto = new Queue<char>(); 
    _alfabeto.Enqueue('1'); 
    _alfabeto.Enqueue('A'); 
    _alfabeto.Enqueue('B'); 
    _alfabeto.Enqueue('C'); 
    _alfabeto.Enqueue('D'); 
    _alfabeto.Enqueue('E'); 
    _alfabeto.Enqueue('F'); 
    _alfabeto.Enqueue('G'); 
    _alfabeto.Enqueue('H'); 
    _alfabeto.Enqueue('I'); 
    _alfabeto.Enqueue('J'); 
    _alfabeto.Enqueue('K'); 
    _alfabeto.Enqueue('L'); 
    _alfabeto.Enqueue('M'); 
    _alfabeto.Enqueue('N'); 
    _alfabeto.Enqueue('O'); 
    _alfabeto.Enqueue('P'); 
    _alfabeto.Enqueue('Q'); 
    _alfabeto.Enqueue('R'); 
    _alfabeto.Enqueue('S'); 
    _alfabeto.Enqueue('T'); 
    _alfabeto.Enqueue('U'); 
    _alfabeto.Enqueue('V'); 
    _alfabeto.Enqueue('W'); 
    _alfabeto.Enqueue('X'); 
    _alfabeto.Enqueue('Y'); 
    _alfabeto.Enqueue('Z'); 

    _paginaAtual = 1; 
    _letraAtual = _alfabeto.Dequeue(); 
} 

public string[] Find(string url) 
{ 
    List<string> _empresas = new List<string>(); 

    if (!_alfabeto.Any() && _letraAtual == ' ') 
    { 
     return _empresas.ToArray(); 
    } 
    var webGet = new HtmlWeb(); 
    var formattedUrl = String.Format(url, _letraAtual, _paginaAtual++); 
    var document = webGet.Load(formattedUrl); 
    var nodes = document.DocumentNode.SelectNodes("//div[@id='conteudo']/div[@class='gratuito']/p/a"); 

    foreach (var node in nodes) 
    { 
     var href = node.GetAttributeValue("href", ""); 
     _empresas.Add(href); 
    } 

    var elUrlProximaPagina = document.DocumentNode.SelectSingleNode("//div[@id='principal']/div[@id='conteudo']/div[@class='paginacao']/a[contains(@class,'nextPage')]"); 
    if (elUrlProximaPagina == null) 
    { 
     _letraAtual = _alfabeto.Any() ? _alfabeto.Dequeue() : ' '; 
     _paginaAtual = 1; 
    } 
    Console.WriteLine(_letraAtual); 
    Console.WriteLine(_paginaAtual); 

    DadoPo.SalvarUrl();   

    return Find(url); 
} 

}

好,現在的誤差在另一個地方,則在 VAR文檔= webGet.Load(formattedUrl)給予OutOfMemoryException異常;

回答

1

在網站上抓取信息N次(例如1000次)之後,將_empresas的內容保留在硬盤(數據庫,物理文件)中。然後清潔_empresas一套新的信息

你在做什麼是幾乎使用所有由CLR允許您的PE內存

namespace WebCrawler.SantaCatarina 
{ 
class SCLinkFinder : ILinkFinder 
{ 
    private readonly Queue<char> _alfabeto; 

    private int _paginaAtual; 
    private char _letraAtual; 

    public SCLinkFinder() 
    { 
     _alfabeto = new Queue<char>(); 
     _alfabeto.Enqueue('1'); 
     _alfabeto.Enqueue('A'); 
     _alfabeto.Enqueue('B'); 
     _alfabeto.Enqueue('C'); 
     _alfabeto.Enqueue('D'); 
     _alfabeto.Enqueue('E'); 
     _alfabeto.Enqueue('F'); 
     _alfabeto.Enqueue('G'); 
     _alfabeto.Enqueue('H'); 
     _alfabeto.Enqueue('I'); 
     _alfabeto.Enqueue('J'); 
     _alfabeto.Enqueue('K'); 
     _alfabeto.Enqueue('L'); 
     _alfabeto.Enqueue('M'); 
     _alfabeto.Enqueue('N'); 
     _alfabeto.Enqueue('O'); 
     _alfabeto.Enqueue('P'); 
     _alfabeto.Enqueue('Q'); 
     _alfabeto.Enqueue('R'); 
     _alfabeto.Enqueue('S'); 
     _alfabeto.Enqueue('T'); 
     _alfabeto.Enqueue('U'); 
     _alfabeto.Enqueue('V'); 
     _alfabeto.Enqueue('W'); 
     _alfabeto.Enqueue('X'); 
     _alfabeto.Enqueue('Y'); 
     _alfabeto.Enqueue('Z'); 

     _paginaAtual = 1; 
     _letraAtual = _alfabeto.Dequeue(); 
    } 

    public string[] Find(string url) 
    { 
     List<string> _empresas = new List<string>(); 

     if (!_alfabeto.Any() && _letraAtual == ' ') 
     { 
      return _empresas.ToArray(); 
     } 
     var webGet = new HtmlWeb(); 
     var formattedUrl = String.Format(url, _letraAtual, _paginaAtual++); 
     var document = webGet.Load(formattedUrl); 
     var nodes = document.DocumentNode.SelectNodes("//div[@id='conteudo']/div[@class='gratuito']/p/a"); 

     foreach (var node in nodes) 
     { 
      var href = node.GetAttributeValue("href", ""); 
      _empresas.Add(href); 
     } 

     var elUrlProximaPagina = document.DocumentNode.SelectSingleNode("//div[@id='principal']/div[@id='conteudo']/div[@class='paginacao']/a[contains(@class,'nextPage')]"); 
     if (elUrlProximaPagina == null) 
     { 
      _letraAtual = _alfabeto.Any() ? _alfabeto.Dequeue() : ' '; 
      _paginaAtual = 1; 
     } 
     Console.WriteLine(_letraAtual); 
     Console.WriteLine(_paginaAtual); 

     //Your code to read _empresas and Persist in database(or file)    

     return Find(url); 
    } 
} 

}

+0

你能更好的解釋嗎?也許有一個例子。| 也許只是做這樣的: 如果(_empresas == 30000){ 對(INT I = 0; I <_empresas;我++){ Database.Link = _empresas } _empresas.empty; } ?或者我誤解了? – Bovo

+0

非常感謝您。 – Bovo

+0

查看上面的變化,我只是將_empresas更改爲方法內部的實例,最後在返回之前保存在數據庫中或追加到txt/xml文件中。你應該停止跳出內存異常 – RollRoll