2010-08-30 20 views
11

jakie są zalety i wady poniższych bibliotek?html skrobanie i css zapytania

Z powyżej Użyłem QP i nie udało się zanalizować nieprawidłowy HTML i simpleDomParser, że ma dobrą pracę, ale to trochę przecieka pamięć ze względu na model obiektu. Ale możesz zachować to pod kontrolą dzwoniąc pod numer $object->clear(); unset($object);, gdy nie potrzebujesz już obiektu.

Czy jest więcej skrobaków? Jakie są twoje doświadczenia z nimi? Zamierzam zrobić z tego wiki społeczności, może stworzymy użyteczną listę bibliotek, które mogą być przydatne podczas skrobania.


zrobiłem kilka testów w oparciu Byrona odpowiedź:

<? 
    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>"; 

i dostał

dom:   0.00359296798706 . Got 115 items 
PQ:   0.010568857193 . Got 115 items 
simple_dom: 0.0770139694214 . Got 115 items 

Odpowiedz

7

Ja używałem wyłącznie prosty HTML DOM aż niektóre jasne SO'ers pokazał mi światło Alleluja .

Wystarczy użyć wbudowanych funkcji DOM. Są napisane w C i części rdzenia PHP. Są szybsze bardziej wydajne niż jakiekolwiek rozwiązania innych firm. W przypadku firebuga otrzymanie zapytania XPath jest bardzo proste. Ta prosta zmiana sprawiła, że ​​skrobaki oparte na php działają szybciej, oszczędzając mój cenny czas.

Moje skrobaki zajmowały około 60 megabajtów, aby zeskrobać 10 witryn z lokami. Stało się tak nawet w przypadku zwykłej poprawki pamięci html dom, o której wspomniałeś.

Teraz moje procesy php nigdy nie przekraczają 8 megabajtów.

Gorąco polecam.

EDIT

Dobrze zrobiłem kilka wzorców. Wbudowany dom jest co najmniej o rząd wielkości szybszy.

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"; 
+0

to nie działa w przypadku nieprawidłowych znaczników. O ile szybciej jest to w porównaniu z prostym domem? – Quamis

+2

** działa ** w przypadku nieprawidłowych znaczników. Nie mam benchmarków, ale jest to co najmniej o rząd wielkości szybsze. Na dużych stronach prosty html dom zajmowałby 1-2 sekundy. Wbudowany DOM robi to w mgnieniu oka. Napisałem już wiele skrobaków i nigdy nie użyłbym prostego html dom na zawsze. –

+0

@Quamis Zwróć uwagę na @ przed loadHtml(). Po usunięciu zobaczysz mnóstwo ostrzeżeń od nieprawidłowego html wymuszonego na drzewie domowym. Działa dla przeglądarek, działa także dla php;) –