note 87320 added to class.domdocument

From: Date: Sun, 30 Nov 2008 07:59:30 +0000
Subject: note 87320 added to class.domdocument
Groups: php.notes 
Request: Send a blank email to php-notes+get-147434@lists.php.net to get a copy of this message
Here is a simple web scraping example using the PHP DOM that tries to get the largest text body of a HTML document. I needed it for a spider that had to show a short description for a page. It assumes that document annotation can be the largest <div>, <td> or <p> element in the page. In the example I show a way to prevent a bug in the DOM as it sometimes just doesn't recognize html encoding. It seems to work if you put charset meta tag right after the head tag of the document. <? $ch= curl_init(); curl_setopt ($ch, CURLOPT_URL, '...put url here...' ); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch,CURLOPT_VERBOSE,1); curl_setopt($ch, CURLOPT_USERAGENT, 'set sth...'); curl_setopt ($ch, CURLOPT_REFERER, '...set sth...'); //just a fake referer curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_POST,0); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 20); $html= curl_exec($ch); $html1= curl_getinfo($ch); //try to get page encoding as it was sent from server if ($html1['content_type']){ $arr= explode('charset=',$html1['content_type']); $csethdr= strtolower(trim($arr[1])); } else { $csethdr= false; } $cset= false; $arr= array(); //This has to replace page meta tags for charset with utf-8, but it doesn't actually help(see the bug info). if (preg_match_all( '/(<meta\s*http-equiv="Content-Type"\s*content="[^;]*; \s*charset=([^"]*?)(?:"|\;)[^>]*>)/' //merge this line ,$html,$arr,PREG_PATTERN_ORDER)){ $cset= strtolower(trim($arr[2][0])); if ($cset!='utf-8'||$cset!=$csethdr){ $new= str_replace($arr[2][0],'utf-8',$arr[1][0]); $html= str_replace($arr[1][0],$new,$html); $cset= $csethdr; } else { $cset= false; } if ($cset=='utf-8'){ $cset= false; } } unset($arr); if ($cset){ $html= iconv($cset,'utf-8',$html); } unset($cset); //solve dom bug $html=preg_replace('/<head[^>]*>/','<head> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8"> ',$html); $dom= new DOMDocument(); $dom->loadHTML($html); $dom->preserveWhiteSpace = false; function getMaxTextBody($dom){ $content = $dom->getElementsByTagname('div'); $content2= $dom->getElementsByTagname('td'); $content3= $dom->getElementsByTagname('p'); $new= array(); foreach ($content as $value) { $new[]= $value; unset($value); } unset($content); foreach ($content2 as $value) { $new[]= $value; unset($value); } unset($content2); foreach ($content3 as $value) { $new[]= $value; unset($value); } unset($content3); $maxlen= 0; $result= ''; foreach ($new as $item) { $str= $item->nodeValue; if (strlen($str)>$maxlen){ $content1= $item->getElementsByTagName('div'); $content2= $item->getElementsByTagname('td'); $content3= $item->getElementsByTagname('p'); $contentnew= array(); foreach ($content1 as $value) { $contentnew[]= $value; unset($value); } unset($content1); foreach ($content2 as $value) { $contentnew[]= $value; unset($value); } unset($content2); foreach ($content3 as $value) { $contentnew[]= $value; unset($value); } unset($content3); if (count($contentnew)==0){ $result= $str; } else { foreach ($contentnew as $value) { $str1= getMaxTextBody($value); $str2= $value->nodeValue; //let's say largest body has more than 50% of the text in its parent if (strlen($str1)*2<strlen($str2)){ $str1= $str2; } if (strlen($str1)*2>strlen($str)&&strlen($str1)>$maxlen){ $result= $str1; } elseif (strlen($str1)>$maxlen){ $result= $str1; } $maxlen= strlen($result); } } $maxlen= strlen($result); unset($contnentnew); } } unset($new); return $result; } print getMaxTextBody($dom); ?> ---- Server IP: 217.75.128.29 Probable Submitter: 91.92.160.2 ---- Manual Page -- http://www.php.net/manual/en/class.domdocument.php Edit -- https://master.php.net/note/edit/87320 Del: integrated -- https://master.php.net/note/delete/87320/integrated Del: useless -- https://master.php.net/note/delete/87320/useless Del: bad code -- https://master.php.net/note/delete/87320/bad+code Del: spam -- https://master.php.net/note/delete/87320/spam Del: non-english -- https://master.php.net/note/delete/87320/non-english Del: in docs -- https://master.php.net/note/delete/87320/in+docs Del: other reasons-- https://master.php.net/note/delete/87320 Reject -- https://master.php.net/note/reject/87320 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#147434) next »