WebCrawler中的OutOfMemoryException

时间:2013-01-17 16:11:07

标签: c# exception out-of-memory

所以我需要保存一个网站的多个链接,但是当它到达64k链接附近时,它会给我一个错误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);
}

}

好的,现在错误出现在另一个地方,它给出了outofmemoryexception var document = webGet.Load(formattedUrl);

1 个答案:

答案 0 :(得分:1)

在网站上抓取信息N次(例如1,000)之后,将_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);
    }
}

}