Я не разбираю этот URL: http://foldmunka.net
$ch = curl_init("http://foldmunka.net"); //curl_setopt($ch, CURLOPT_NOBODY, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //not necessary unless the file redirects (like the PHP example we're using here) $data = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); clearstatcache(); if ($data === false) { echo 'cURL failed'; exit; } $dom = new DOMDocument(); $data = mb_convert_encoding($data, 'HTML-ENTITIES', "utf-8"); $data = preg_replace('/<\!\-\-\[if(.*)\]>/', '', $data); $data = str_replace('<![endif]-->', '', $data); $data = str_replace('<!--', '', $data); $data = str_replace('-->', '', $data); $data = preg_replace('@<script[^>]*?>.*?</script>@si', '', $data); $data = preg_replace('@<style[^>]*?>.*?</style>@si', '', $data); $data = mb_convert_encoding($data, 'HTML-ENTITIES', "utf-8"); @$dom->loadHTML($data); $els = $dom->getElementsByTagName('*'); foreach($els as $el){ print $el->nodeName." | ".$el->getAttribute('content')."<hr />"; if($el->getAttribute('title'))$el->nodeValue = $el->getAttribute('title')." ".$el->nodeValue; if($el->getAttribute('alt'))$el->nodeValue = $el->getAttribute('alt')." ".$el->nodeValue; print $el->nodeName." | ".$el->nodeValue."<hr />"; }
Мне нужно последовательно атрибуты alt, title и простой текст, но на этой странице я не могу получить доступ к узлам в теге body.
Вот решение с DomDocument и DOMXPath. Он намного короче и работает намного быстрее (~ 100 мс против ~ 2300 мс), чем другое решение с помощью простого HTML DOM Parser.
<?php function makePlainText($source) { $dom = new DOMDocument(); $dom->loadHtmlFile($source); // use this instead of loadHtmlFile() to load from string: //$dom->loadHtml('<html><title>Hello</title><body>Hello this site<img src="asdasd.jpg" alt="alt attr" title="title attr"><a href="open.php" alt="alt attr" title="title attr">click</a> Some text.</body></html>'); $xpath = new DOMXPath($dom); $plain = ''; foreach ($xpath->query('//text()|//a|//img') as $node) { if ($node->nodeName == '#cdata-section') continue; if ($node instanceof DOMElement) { if ($node->hasAttribute('alt')) $plain .= $node->getAttribute('alt') . ' '; if ($node->hasAttribute('title')) $plain .= $node->getAttribute('title') . ' '; } if ($node instanceof DOMText) $plain .= $node->textContent . ' '; } return $plain; } echo makePlainText('http://foldmunka.net');
Я не уверен, что получаю то, что делает этот скрипт – операции замены выглядят как попытка санитарии, но я не уверен, что делать, если вы просто извлекаете некоторые части кода, но попробовали ли вы Simple HTML DOM Browser ? Он может более легко обрабатывать парсинг. Ознакомьтесь с примерами.
Вот простое решение Html DOM Parser для сравнения. Он аналогичен для решения DomDocument , но этот сложнее и работает намного медленнее (~ 2300 мс против DomDocument ~ 100 мс), поэтому я не рекомендую его использовать:
Обновлено для работы с <img>
элементами внутри <a>
элементов.
<?php require_once('simple_html_dom.php'); // we are needing this because Simple Html DOM Parser's callback handler // doesn't handle arguments static $processed_plain_text = ''; define('LOAD_FROM_URL', 'loadfromurl'); define('LOAD_FROM_STRING', 'loadfromstring'); function callback_cleanNestedAnchorContent($element) { if ($element->tag == 'a') $element->innertext = makePlainText($element->innertext, LOAD_FROM_STRING); } function callback_buildPlainText($element) { global $processed_plain_text; $excluded_tags = array('script', 'style'); switch ($element->tag) { case 'text': // filter when 'text' is descendant of 'a', because we are // processing the anchor tags with the required attributes // separately at the 'a' tag, // and also filter out other unneccessary tags if (($element->parent->tag != 'a') && !in_array($element->parent->tag, $excluded_tags)) $processed_plain_text .= $element->innertext . ' '; break; case 'img': $processed_plain_text .= $element->alt . ' '; $processed_plain_text .= $element->title . ' '; break; case 'a': $processed_plain_text .= $element->alt . ' '; $processed_plain_text .= $element->title . ' '; $processed_plain_text .= $element->innertext . ' '; break; } } function makePlainText($source, $mode = LOAD_FROM_URL) { global $processed_plain_text; if ($mode == LOAD_FROM_URL) $html = file_get_html($source); elseif ($mode == LOAD_FROM_STRING) $html = str_get_dom ($source); else return 'Wrong mode defined in makePlainText: ' . $mode; $html->set_callback('callback_cleanNestedAnchorContent'); // processing with the first callback to clean up the anchor tags $html = str_get_html($html->save()); $html->set_callback('callback_buildPlainText'); // processing with the second callback to build the full plain text with // the required attributes of the 'img' and 'a' tags, and excluding the // unneccessary ones like script and style tags $html->save(); $return = $processed_plain_text; // cleaning the global variable $processed_plain_text = ''; return $return; } //$html = '<html><title>Hello</title><body>Hello <span>this</span> site<img src="asdasd.jpg" alt="alt attr" title="title attr"><a href="open.php" alt="alt attr" title="title attr">click <span><strong>HERE</strong></span><img src="image.jpg" title="IMAGE TITLE INSIDE ANCHOR" alt="ALTINACNHOR"></a> Some text.</body></html>'; echo makePlainText('http://foldmunka.net'); //echo makePlainText($html, LOAD_FROM_STRING);