HTML Scraping и CSS-запросы
-
25-09-2019 - |
Вопрос
Каковы преимущества и недостатки следующих библиотек?
Из приведенного выше я использовал QP, и он не смог проанализировать неверный HTML и SimpledMarser, который делает хорошую работу, но это вроде утечки памяти из-за модели объекта. Но вы можете держать это под контролем, позвонив $object->clear(); unset($object);
Когда вам больше не нужен объект.
Есть ли еще скребки? Каковы ваши переживания с ними? Я собираюсь сделать это сообщество Wiki, возможно, мы построим полезный список библиотек, которые могут быть полезны при сострании.
Я сделал некоторые тесты на основе ответа Байрона:
<?
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 Simple. Это простые изменения сделали мои скребки на основе PHP бегать быстрее, сохраняя мое драгоценное время.
Мои скребки использовали ~ 60 мегабайт, чтобы скорсировать 10 сайтов асинронизм с завитками. Это было даже при простом HTML DOM-памяти, которую вы упомянули.
Теперь мои процессы PHP никогда не проходят выше 8 мегабайт.
Настоятельно рекомендуется.
РЕДАКТИРОВАТЬ
Хорошо, я сделал несколько ориентиров. Встроенный в доме, по крайней мере, порядка быстрее.
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";