DomDocument sınıf yapamaz erişim DOMNode

3 Cevap php

Ben bu url ayrıştırma yok: 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 />";
}

I sequentially alt, başlık özellikleri ve basit metin, ama bu sayfa i vücut etiketi içinde düğümlerin erişemiyor gerekir.

3 Cevap

Burada DomDocument ve DOMXPath olan bir çözümdür. Bu çok daha kısa ve çok daha hızlı (~ ~ 2300ms karşı 100ms) Basit HTML DOM Parser ile diğer çözümlerden daha çalışır.

<?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');

Ben bu script ne alıyorum emin değilim - değiştirin işlemleri sanitasyon bir girişim gibi görünüyor ama sadece bazı kod parçalarını ayıklamak eğer ben, ne için emin değilim - ama {denedi [(0)]}? Bu daha kolay ayrıştırma kısmını ele almak mümkün olabilir. Örnekler göz atın.

Burada karşılaştırma için sadece bir Simple Html DOM Parser çözümdür. Bu çıkış DomDocument solution 's benzer, ama bu bir daha karmaşık ve (~ domBelgesi en ~ 100ms karşı 2300ms) daha yavaş çalışır, bu yüzden don't recommend kullanmak bulunuyor:

Updated <a> öğeleri içinde <img> öğeleriyle çalışmak.

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