Pergunta

Quais são as vantagens e desvantagens das seguintes bibliotecas?

Desde o exposto, usei o QP e ele não analisou o HTML inválido e o SimpleDomParser, que faz um bom trabalho, mas meio que vazar memória por causa do modelo de objeto. Mas você pode manter isso sob controle ligando $object->clear(); unset($object); Quando você não precisa mais de um objeto.

Existem mais raspadores? Quais são suas experiências com eles? Vou fazer disso um wiki da comunidade, que possamos construir uma lista útil de bibliotecas que possam ser úteis ao raspar.


Eu fiz alguns testes baseados na resposta de Byron:

    <?
    include("lib/simplehtmldom/simple_html_dom.php");
    include("lib/phpQuery/phpQuery/phpQuery.php");


    echo "<pre>";

    $html = file_get_contents("http://stackoverflow.com/search?q=favorite+programmer+cartoon");
    $data['pq'] = $data['dom'] = $data['simple_dom'] = array();

    $timer_start = microtime(true);

    $dom = new DOMDocument();
    @$dom->loadHTML($html);
    $x = new DOMXPath($dom);

    foreach($x->query("//a") as $node)
    {
         $data['dom'][] = $node->getAttribute("href");
    }

    foreach($x->query("//img") as $node)
    {
         $data['dom'][] = $node->getAttribute("src");
    }

    foreach($x->query("//input") as $node)
    {
         $data['dom'][] = $node->getAttribute("name");
    }

    $dom_time =  microtime(true) - $timer_start;
    echo "dom: \t\t $dom_time . Got ".count($data['dom'])." items \n";






    $timer_start = microtime(true);
    $doc = phpQuery::newDocument($html);
    foreach( $doc->find("a") as $node)
    {
       $data['pq'][] = $node->href;
    }

    foreach( $doc->find("img") as $node)
    {
       $data['pq'][] = $node->src;
    }

    foreach( $doc->find("input") as $node)
    {
       $data['pq'][] = $node->name;
    }
    $time =  microtime(true) - $timer_start;
    echo "PQ: \t\t $time . Got ".count($data['pq'])." items \n";









    $timer_start = microtime(true);
    $simple_dom = new simple_html_dom();
    $simple_dom->load($html);
    foreach( $simple_dom->find("a") as $node)
    {
       $data['simple_dom'][] = $node->href;
    }

    foreach( $simple_dom->find("img") as $node)
    {
       $data['simple_dom'][] = $node->src;
    }

    foreach( $simple_dom->find("input") as $node)
    {
       $data['simple_dom'][] = $node->name;
    }
    $simple_dom_time =  microtime(true) - $timer_start;
    echo "simple_dom: \t $simple_dom_time . Got ".count($data['simple_dom'])." items \n";


    echo "</pre>";

e pegou

dom:         0.00359296798706 . Got 115 items 
PQ:          0.010568857193 . Got 115 items 
simple_dom:  0.0770139694214 . Got 115 items 
Foi útil?

Solução

Eu costumava usar o html dom simples exclusivamente até que alguns mais brilhantes me mostrassem o alelujah leve.

Basta usar as funções DOM embutidas. Eles são escritos em C e parte do núcleo do PHP. Eles são mais rápidos mais eficientes do que qualquer solução de terceiros. Com o Firebug, obter uma consulta XPath é Muey Simple. Essa mudança simples fez meus raspadores baseados em PHP funcionarem mais rapidamente, economizando meu precioso tempo.

Meus raspadores costumavam tomar ~ 60 megabytes para raspar 10 locais de forma assíncrona com cacho. Isso foi mesmo com a simples correção de memória HTML DOM que você mencionou.

Agora meus processos PHP nunca ultrapassaram 8 megabytes.

Altamente recomendado.

EDITAR

Ok, eu fiz alguns benchmarks. O DOM construído é pelo menos uma ordem de magnitude mais rápida.

Built in php DOM: 0.007061
Simple html  DOM: 0.117781

<?
include("../lib/simple_html_dom.php");

$html = file_get_contents("http://stackoverflow.com/search?q=favorite+programmer+cartoon");
$data['dom'] = $data['simple_dom'] = array();

$timer_start = microtime(true);

$dom = new DOMDocument();
@$dom->loadHTML($html);
$x = new DOMXPath($dom); 

foreach($x->query("//a") as $node) 
{
     $data['dom'][] = $node->getAttribute("href");
}

foreach($x->query("//img") as $node) 
{
     $data['dom'][] = $node->getAttribute("src");
}

foreach($x->query("//input") as $node) 
{
     $data['dom'][] = $node->getAttribute("name");
}

$dom_time =  microtime(true) - $timer_start;

echo "built in php DOM : $dom_time\n";

$timer_start = microtime(true);
$simple_dom = new simple_html_dom();
$simple_dom->load($html);
foreach( $simple_dom->find("a") as $node)
{
   $data['simple_dom'][] = $node->href;
}

foreach( $simple_dom->find("img") as $node)
{
   $data['simple_dom'][] = $node->src;
}

foreach( $simple_dom->find("input") as $node)
{
   $data['simple_dom'][] = $node->name;
}
$simple_dom_time =  microtime(true) - $timer_start;

echo "simple html  DOM : $simple_dom_time\n";
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top