ilch Forum » Allgemein » HTML, PHP, SQL,... » Wie eine HTML mit Php parsen und auswert

Geschlossen
  1. #1
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    Wie eine HTML mit Php parsen und auswerten?

    Ich habe bisher Stundenlang gesucht, doch nichts verwertbares gefunden.
    Meine Hilfsmittel sind simple_html_dom und mein Code ist:

    HTML-Code:

    <div id="ts3_viewer">
                <div class="server_green">
                    <a href="ts3server://xxx.xxx.xxx.xxx/?port=xxxx" title="TeamSpeak3 Server">
                        TSServer
                    </a>
                </div>
                <div class="item">
                    <div class="label channel_green">
                        Eingangshalle
                    </div>
                    <div class="flags">
                    </div>
                    <div class="item">
                        <div class="label channel_green">
                            Unterhaltung
                        </div>
                        <div class="flags">
                        </div>
                    </div>
                </div>
                <div class="item">
                    <div class="label channel_green">
                        World of Warcraft
                    </div>
                    <div class="flags">
                    </div>
                    <div class="item">
                        <div class="label channel_green">
                            10er Raid
                        </div>
                        <div class="flags">
                        </div>
                    </div>
                    <div class="item">
                        <div class="label channel_green">
                            Instanzen1
                        </div>
                        <div class="flags">
                        </div>
                    </div>
                    <div class="item">
                        <div class="label channel_green">
                            Instanzen2
                        </div>
                        <div class="flags">
                        </div>
                    </div>
                </div>
                <div class="item">
                    <div class="label channel_yellow">
                        Offizier
                    </div>
                    <div class="flags">
                    </div>
                </div>
                <div class="item">
                    <div class="label channel_green">
                        AFK
                    </div>
                    <div class="flags">
                    </div>
                    <div class="item">
                        <div class="label mic_disabled">
                            Ghostrider
                        </div>
                        <div class="flags">
                        </div>
                    </div>
                </div>
            </div>



    Wie man bereits sieht, ist der Code sehr dynamisch. Leider deswegen funktioniert mein Parser nicht.

    Aufgebaut hatte ich ihn mit einer Rekursion,
    der Abfrage, ob das Aktuelle Element noch weitere div's enthält, wenn ja, wieder Rekursion. Wenn nein, dann soll ers in eine Datenbank scheiben. (Das mit Datenbanken kapier ich alles)

    Wenn mir da jemand helfen könnte wäre ich sehr dankbar.

    MFG

    ! Bitte Code im vorgesehenen Tag [code] setzen. Siehe gesperrtes Bild über dem Eingabefeld. BBCode Hilfe. Gruß Lord|S. !


    Zuletzt modifiziert von Lord|Schirmer am 11.09.2012 - 17:20:48
    0 Mitglieder finden den Beitrag gut.
  2. #2
    User Pic
    Mairu Coder
    Registriert seit
    16.06.2006
    Beiträge
    15.334
    Beitragswertungen
    386 Beitragspunkte
    Hat mich interessiert, aber mit google bin ich eigentlich relativ schnell fündig geworden, ich denke mal code.google.com/p/phpquery/ ist genau das wonach du suchst.

    Alternativ könnte man auch mit über DOMDocument selbst durch alle Elemente suchen, ggf. unter der Verwendung von xpath, allerdings sollte phpquery die einfachere Methode sein.
    Und auch immer mal ein Blick auf die FAQ werfen. | Mairus Ilchseite
    0 Mitglieder finden den Beitrag gut.
  3. #3
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    Vielen Dank, doch wenn du weißt wie man damit umgehen kann würde ich mich freuen wenn du mir für mein Beispiel eine Anwendung zeigen könntest.
    Denn ich blick nicht so ganz duch die API durch...
    Trotzalldem die BESTE Lösung für mich, ich setz mich mal damit auseinander. Danke

    ZitatZitat geschrieben von NotEnoughForYou;18705932
    Wie nutzt du denn den simple_html_dom Parser ? Was genau funktioniert nicht ?


    ich habe bisher so damit gearbeitet:

    <?php
    $html = file_get_html("./content.php");
        parse($html);
        
        function parse($html) {
            if (strpos("div", $html) === false) {
                //<-- Eintrag in MySQL Database -->
                echo $html->plaintext."***<br />";
            } else {
                foreach ($html->find('div') as $e) {
                    parse($e);
                }
            }
        }
    ?>
    Hier mal ein Code der mir dabei ausgeworfen wird:

    ZitatZitat
    TSserver ***
    Eingangshalle ***
    ***
    Unterhaltung ***
    ***
    Unterhaltung ***
    ***
    Eingangshalle ***
    ***
    Unterhaltung ***
    ***
    Unterhaltung ***
    ***
    World of Warcraft ***
    ***
    10er Raid ***
    ***
    10er Raid ***
    ***
    Instanzen1 ***
    ***
    Instanzen1 ***
    ***
    Instanzen2 ***
    ***
    Instanzen2 ***
    ***
    World of Warcraft ***
    ***
    10er Raid ***
    ***
    10er Raid ***
    ***
    Instanzen1 ***
    ***
    Instanzen1 ***
    ***
    Instanzen2 ***
    ***
    Instanzen2 ***
    ***
    Offizier ***
    ***
    Offizier ***
    ***
    AFK ***
    ***
    Ghostrider ***
    ***
    Ghostrider ***
    ***
    AFK ***
    ***
    Ghostrider ***
    ***
    Ghostrider ***
    ***
    TSserver ***
    Eingangshalle ***
    ***
    Unterhaltung ***
    ***
    Unterhaltung ***
    ***
    Eingangshalle ***
    ***
    Unterhaltung ***
    ***
    Unterhaltung ***
    ***
    World of Warcraft ***
    ***
    10er Raid ***
    ***
    10er Raid ***
    ***
    Instanzen1 ***
    ***
    Instanzen1 ***
    ***
    Instanzen2 ***
    ***
    Instanzen2 ***
    ***
    World of Warcraft ***
    ***
    10er Raid ***
    ***
    10er Raid ***
    ***
    Instanzen1 ***
    ***
    Instanzen1 ***
    ***
    Instanzen2 ***
    ***
    Instanzen2 ***
    ***
    Offizier ***
    ***
    Offizier ***
    ***
    AFK ***
    ***
    Ghostrider ***
    ***
    Ghostrider ***
    ***
    AFK ***
    ***
    Ghostrider ***
    ***
    Ghostrider ***
    ***
    --> Problem bei der sache ist nur, dass mir alles doppelt und dreifach ausgegeben wird. Ich würde aber gerne den Inhalt analysieren und weiterverwerten.

    MFG


    Zuletzt modifiziert von Ghostrider5 am 12.09.2012 - 14:48:33
    0 Mitglieder finden den Beitrag gut.
  4. #4
    User Pic
    Rock@wulf Hall Of Fame
    Registriert seit
    03.06.2004
    Beiträge
    3.282
    Beitragswertungen
    239 Beitragspunkte
    hmm ich denke du hast da nen Logik Fehler zunge

    dein script bewirkt meiner Meinung nach das nach jedem div eine ausgabe erfolgt zunge

    da scheint es egal zu sein ob ein /div folgt ^^

    Im endeffekt müsstest du alle schon verwerteten Div container ausschließen

    evtl hilft das :

    simplehtmldom.sourceforge.net/
    Meine Postings repräsentieren meine Meinung wenn nicht anders gekennzeichnet.
    MFG Rock@wulf
    0 Mitglieder finden den Beitrag gut.
  5. #5
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    Das ist genau der Parser den ich benutze. Die Seite zeigt mir aber kein Beispiel für Nested Div'S.... Ich würde mich freuen wenn du mir da etwas weiter helfen könntest.

    MFG
    0 Mitglieder finden den Beitrag gut.
  6. #6
    User Pic
    Rock@wulf Hall Of Fame
    Registriert seit
    03.06.2004
    Beiträge
    3.282
    Beitragswertungen
    239 Beitragspunkte
    Eh versuch es doch mal so:

    $x=$html->find('div', 0)->innertext;

    um andere divs aufzurufen einfach

    $x=$html->find('div', 1)->innertext;
    $x=$html->find('div', 2)->innertext;

    usw

    steht im punkt how to modifiy

    bzw scraping slashdot auch interessant zu dem thema

    // Find Nested <div> tags
    $es = $html->find('div div div');

    // Find all <li> in <ul>
    foreach($html->find('ul') as $ul)
    {
    foreach($ul->find('li') as $li)
    {
    // do something...
    }
    }

    // Find first <li> in first <ul>
    $e = $html->find('ul', 0)->find('li', 0);

    lesen bildet
    simplehtmldom.sourceforge.net/manual.htm

    :-)

    Zuletzt modifiziert von Rock@wulf am 12.09.2012 - 16:10:28
    Meine Postings repräsentieren meine Meinung wenn nicht anders gekennzeichnet.
    MFG Rock@wulf
    0 Mitglieder finden den Beitrag gut.
  7. #7
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    I know.
    Nur dynamisch ist das ganze dann nicht mehr.

    Mein Problem ist ja genau das. Verstehe, was du meinst mit dem find('div', 1) ..... Aber, wenn ich mir nicht per Index ein wert ausgeben lasse, bekomm ich das ganze array. Soll heißen ist auch wieder dynamisch und im Prinzip dasselbe.....

    Danke aber trotzdem. Und ja. Ich kenne die API, nur ich werde daraus nicht schlau
    0 Mitglieder finden den Beitrag gut.
  8. #8
    User Pic
    Mairu Coder
    Registriert seit
    16.06.2006
    Beiträge
    15.334
    Beitragswertungen
    386 Beitragspunkte
    Also hier eine Lösung mit phpquery (also ein jQuery Klon für php)

    <?php
    
    include 'phpQuery-onefile.php';
    
    $html = file_get_contents('input.html');
    
    $newDocumentHTML = phpQuery::newDocumentHTML($html);
    
    function getChannels(DOMElement $item)
    {
        $output = array('name' => '', 'subchannels' => array());
        $label = pq('div[class^="label"]:first', $item);
        $output['name'] = trim(pq($label)->text());
        
        foreach (pq('div.item', $item) as $subitem) {
            $output['subchannels'][] = getChannels($subitem);
        }
        return $output;
    }
    
    $channels = array();
    foreach (pq('#ts3_viewer > div.item') as $item) {
        /* @var $item DOMElement */
        $channels[] = getChannels($item);
        
        echo htmlspecialchars(pq($item)->html()), '<hr />';
    }
    
    var_dump($channels);


    Hier noch eine Alternative nur mit PHP Bordmitteln

    <?php
    $html = file_get_contents('input.html');
    
    $xml = new SimpleXMLElement($html);
    
    $ts3viewer = current($xml->xpath("/div[@id='ts3_viewer']"));
    
    $items = $ts3viewer->xpath("div[@class='item']");
    
    function getChannels ($items)
    {
        $output = array();
        foreach ($items as $item) {
            $channel = array();
            /* @var $item SimpleXmlElement */
            $channel['name'] = trim((string) $item->div);
            $tmp = (array) $item->div;
            $channel['subchannels'] = getChannels(array_slice($tmp, 3));
            $output[] = $channel;
        }
        return $output;
    }
    
    $channels = getChannels($items);
    
    var_dump($channels);



    Zuletzt modifiziert von Mairu am 12.09.2012 - 22:51:13
    Und auch immer mal ein Blick auf die FAQ werfen. | Mairus Ilchseite
    1 Mitglieder finden den Beitrag gut.
  9. #9
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    Vielen Vielen Dank Mairu!!!!

    Ich habe eben erst wieder nachgesehen.
    Habe gerade den Code umgesetzt.
    Ich werde später noch einen Link dazustellen.
    0 Mitglieder finden den Beitrag gut.
  10. #10
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    Mairu, ich habe gestern festagestellt, dass sobald sich User in der 3. Ebene befinden, diese Doppelt aufgeführt werden.
    Ich schreibe dir mal einen Link zu der Tabelle, welche ich ausgebe:

    ghostrider.pf-control.de/tsnutzung.php?serverip=188.40.205.15&port=12345
    Mein Parser, aus deiner 1.Version:
    include 'phpQuery-onefile.php';
    $html = file_get_contents(    ); #hab ich mal weggelassen aus Datenschutzrechtlichen Gründen!!
    $newDocumentHTML = phpQuery::newDocumentHTML($html);
    function getChannels(DOMElement $item, $subvar, $serverip, $port)
    {
    	$output = array('name' => '', 'subchannels' => array());
    	$label = pq('div[class^="label"]:first', $item);
    	$output['name'] = trim(pq($label)->text());
    	if (strpos(pq('div[class^="label"]:first', $item), 'channel') === FALSE) {
    		//$temp = 'U'; #USER
    		$temp = pq('div[class^="label"]:first', $item);
    	} else {
    		$temp = 'C';   #CHANNEL
    	}
    	
    	#MySQL Updaten //Wegen MySQL-Injections ausgeblendet!
    	
    	foreach (pq('div.item', $item) as $subitem) {
    		$output['subchannels'][] = getChannels($subitem, $subvar + 1, $serverip, $port);
    	}
    	return $output;
    }
     
    $channels = array();
    foreach (pq('#ts3_viewer > div.item') as $item) {
    	/* @var $item DOMElement */
    	$channels[] = getChannels($item, 1, $serverip, $port);
    }


    Ich habe nochmal vor das mit dem 2. Code von dir zu testen, doch ich vermute das dies ähnlich enden wird...

    Ergebnis:
    Fatal error: Call to a member function xpath() on a non-object (... Mehr wollte ich aus Sicherheitsgründen nicht posten!)


    Ich danke dir vielmals lächeln
    Würde mich freuen wenn du mir nochmals helfen könntest zwinker

    MFG


    Zuletzt modifiziert von Ghostrider5 am 15.09.2012 - 17:45:14
    0 Mitglieder finden den Beitrag gut.
  11. #11
    User Pic
    Mairu Coder
    Registriert seit
    16.06.2006
    Beiträge
    15.334
    Beitragswertungen
    386 Beitragspunkte
    Beim überschauen vom Zend Framework hab ich auch dort eine Komponente gesehen, welche man da verwenden könnte. Welche Version von PHP hast du auf deinem Webspace.

    Ich bräuchte dann zum Testen möglichst einen Testcode wie aus deinem ersten Post.

    Welche Informationen brauchst du überhaupt, ggf. kannst du den TS3 Server direkt ansprechen und einfacher an die Informationen kommen, also das Ergebnis eines TS3Viewers zu parsen.
    Und auch immer mal ein Blick auf die FAQ werfen. | Mairus Ilchseite
    0 Mitglieder finden den Beitrag gut.
  12. #12
    User Pic
    Ghostrider5 Mitglied
    Registriert seit
    11.09.2012
    Beiträge
    7
    Beitragswertungen
    0 Beitragspunkte
    Das ist ja gerade der Punkt. es gibt massenhaft TSViewer, die die Schnittstelle des Queryports nutzen, doch keinen einzigen, der ab dem TS-Viewer erst beginnt.
    Unter anderem bin ich gezwungen den TS-Viewer zu parsen, da der Queryport geblockt wird.

    Hier mal ein code, der Funktioniert:
    <?php
    $url = "http://www.exmaple.com";
    
    $sourcestring = file_get_contents($url);
    
    preg_match_all('@<div class="label ([\w]*)">([^<]*)</div>@ms',$sourcestring,$matches);
    
    $channels =  array_map('trim', $matches['2']);
    
    foreach($channels as $channel){
        echo "{$channel} <br/>";
    }
    ?>

    Doch hab ich selbst das Problem, dass ich hier keinerlei Informationen über die labels herausbekomme. Deshalb bevorzuge ich doch mehr deine Version

    Wenn du willst könnten wir uns auf dem TS-Server mal unterhalten.

    Ts-Viewer:
    code.4b42.com/voiceserver/viewer/teamspeak3/188.40.205.15/10011/12345

    Um zu connecten einfach auf den Servernamen klicken lachen


    Zuletzt modifiziert von Ghostrider5 am 15.09.2012 - 18:24:04
    0 Mitglieder finden den Beitrag gut.
Geschlossen

Zurück zu HTML, PHP, SQL,...

Optionen: Bei einer Antwort zu diesem Thema eine eMail erhalten