2010-08-30 8 views
11

Каковы преимущества и недостатки следующих библиотек?html скребок и css-запросы

Из выше я использовал QP и он не смог разобрать недействительный HTML и simpleDomParser, что делает хорошую работу, но это своего рода утечки из-за объектной модели. Но вы можете держать это под контролем, вызывая $object->clear(); unset($object);, когда вам больше не нужен объект.

Есть ли еще скребки? Каковы ваши впечатления от них? Я собираюсь сделать это вики-сообществом, возможно, мы создадим полезный список библиотек, которые могут быть полезны при очистке.


я сделал несколько тестов на основе ответа Байрона:

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

и получил

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

ответ

7

Я имел обыкновение использовать простой HTML DOM исключительно до тех пор некоторые яркие SO'ers показал мне свет Аллилуйя ,

Просто используйте встроенные функции DOM. Они написаны на C и являются частью ядра PHP. Они более эффективны, чем любое стороннее решение. С firebug, получение запроса XPath является muey простым. Это простое изменение заставило мои скребки на основе php работать быстрее, сохраняя мое драгоценное время.

Мои скребки использовали около 60 мегабайт, чтобы скрестить 10 сайтов асинхронно с завитом. Это было даже с простым исправлением памяти html dom, о котором вы говорили.

Теперь мои процессы php никогда не превышают 8 мегабайт.

Настоятельно рекомендуется.

EDIT

Хорошо я сделал несколько тестов. Построенный в dom, по крайней мере, на порядок выше.

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

Это не работает для недействительной разметки. Насколько быстрее это против простого дома? – Quamis

+2

Это ** работает ** для недопустимой разметки. У меня нет контрольных показателей, но, по крайней мере, на порядок выше. На больших страницах простой html dom займет 1-2 секунды. Встроенный DOM делает это в мгновение ока. Я написал много скребок с этим, и я никогда не буду использовать простой html dom для чего-либо снова. –

+0

@Quamis Обратите внимание на @ перед loadHtml(). С удалением вы увидите тонну предупреждений о недействительном html, принуждаемом к дереву dom. Работает для браузеров, работает для php тоже;) –

Смежные вопросы