каковы преимущества и недостатки следующих библиотек?
Из вышеизложенного я использовал QP, и он не смог разобрать недопустимый HTML и simpleDomParser, который отлично справляется с этим, но он похож на утечку памяти из-за объектной модели. Но вы можете держать это под контролем, вызывая $object->clear(); unset($object);
$object->clear(); unset($object);
с $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>";
в<? 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>";
в<? 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
Я использовал простой html dom исключительно до тех пор, пока некоторые яркие SO'ers не показали мне свет аллилуйя.
Просто используйте встроенные функции DOM. Они написаны на C и являются частью ядра PHP. Они более эффективны, чем любое стороннее решение. С firebug, получение запроса XPath является muey простым. Это простое изменение заставило мои скребки на основе php работать быстрее, сохраняя мое драгоценное время.
Мои скребки использовали ~ 60 мегабайт, чтобы скрестить 10 сайтов асинхронно с завитом. Это было даже с простым исправлением памяти html dom, о котором вы говорили.
Теперь мои php-процессы никогда не превышают 8 мегабайт.
Настоятельно рекомендуется.
РЕДАКТИРОВАТЬ
Хорошо, я сделал несколько тестов. Построенный в 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";
в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";