simplehtmldom-parser einrichten - auf einem LAMP unter MX-Linux

tarifa

Lieutenant
Registriert
März 2020
Beiträge
625
Hallo und guten Abend,


vorweg: bin ziemlich neu hier in dem Forum - bin Tarifa - und setze Linux ein - schon seit einger Zeit.

ich habe eine MX-Linux mit einem LAMP installiert
Nun hab ich noch ein PHP Simple HTML DOM Parser (http://simplehtmldom.sourceforge.net/) eingesetzt:
Anfangs hab ich noch Fehlermeldungen erhalten - wohl weil der DOM Parser nicht sauber resp. nicht am komplett korrekten Platz installiert war.

Wie und auf welche Weise kann man das denn am besten checken!?
hier ist die Ordnerstruktur meines LAMP auf dem MX-Rechner:


Code:
/var/www/domparser/
- hier ist das Test- bzw. Parserscript

Code:
 /var/www/dev/
- hier ist der simplehtmldom-parser - als includ sozusagen-

Das sollte doch so passen oder?!

generell - sollte das dann auch zu testen sein.

Code:
<?php
// Include the php dom parser
include('dev/simple_html_dom.php');';
// Create DOM from URL or file
$html = file_get_html('http://www.google.com');
// Find all images
foreach($html->find('img') as $element)
       echo $element->src . '<br>';
// Find all links
foreach($html->find('a') as $element)
       echo $element->href . '<br>';
?>
 
Zuletzt bearbeitet:
Hi tarifa,

ich bin ebenfalls neu hier, ebenfalls Linux seit einiger Zeit.

also erstens ist der DOM Parser vielleicht nicht nötig da es die DOMDocument Klasse gibt.

Ein Beispiel für eine mögliche Anwendung wäre hier zu finden:
https://stackoverflow.com/a/17445554/1165121

Wie auch immer - der Pfad im include Befehl ist relativ oder absolut anzugeben.

Du hast jetzt:
/var/www/domparser/index.php
/var/www/dev/simple_html_dom.php

dann schreibst du im include in der /var/www/domparser/index.php include('../dev/simple_html_dom.php');

Alternativ und auch um das verschieben der Dateien zu erleichtern kannst du eine Konstante für den Absoluten Rootpfad deiner Anwendung festlegen, "ANWENDUNGSPREFIX" ersetze mit dem Namen deiner Anwendung:

Code:
if ( ! defined( 'ANWENDUNGSPREFIX_ABSPATH' ) ) {
  define( 'ANWENDUNGSPREFIX_ABSPATH', dirname( __FILE__ ) . '/' );
}

Diesen Code würde ich in der index.php in /var/www/ definieren und beide Dateien von dort aus inkludieren mit include(ANWENDUNGSPREFIX_ABSPATH . 'dev/simple_html_dom.php');

In den Dateien kannst du dadurch auch gleich dafür sorgen, das diese nicht direkt aufgerufen werden, ergänze am Anfang:
Code:
if ( ! defined('ANWENDUNGSPREFIX_ABSPATH') ) {
    die('Invalid request.');
}

heir noch ein einfaches Beispiel mit DOMDocument (Quelle):

Code:
$dom = new DomDocument();
$dom->load('http://www.google.com');
$images = $dom->documentElement->getElementsByTagName('img');
echo '<pre>' . var_dump($images) . '<pre>';
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: tarifa
Hallo Netzgestaltung,:)


vielen Dank für deine rasche Antwort - das ist sehr hilfreich. ;)

Linux ist schon klasse: Im Büro verwende ich Win und @home Linux (neuerdings MX-Linux) früher immer OpenSuse und Manjaro oder auch Ubuntu. Mit MX bin ich sehr zufrieden.

Danke für deine Tipps bzgl. DOM Parserr und DOMDocument-Klasse. Ich sehe mir das Beispiel auf Stackoverflow auch gleich heute Abend an.


also erstens ist der DOM Parser vielleicht nicht nötig da es die DOMDocument Klasse gibt.
Ein Beispiel für eine mögliche Anwendung wäre hier zu finden:
https://stackoverflow.com/a/17445554/1165121
Wie auch immer - der Pfad im include Befehl ist relativ oder absolut anzugeben.
Du hast jetzt:
/var/www/domparser/index.php
/var/www/dev/simple_html_dom.php
dann schreibst du im include in der /var/www/domparser/index.php include('../dev/simple_html_dom.php');

So werde ich das machen. Ich habe eine Aufgabe die ggf. auch einfacher zu lösen ist - aber ich will das gerne mal mit PHP versuchen.

Ziel ist von dieser Seite ein paar Daten /(die ersten 20 Einträge) zu beziehen. Dort werden aktuell neue Einträge zu Stellen in Europäischen Freiwilligendienst-Stellen gelistet. Wenn ich von diesen Einträgen aktuell immer ca 20 Records beziehen kann wäre das super.

Die Seite: https://europa.eu/youth/volunteering/organisations_en#open


Ansätze: also - mit regular expression oder SimpleDOM anzufangen ist das eine.

Aber für die Zielseite ist es ggf auch interessant mit einer PHP-DOMDocument-Extension zu arbeiten.
DOM ist m.E. sehr leistungsfähig - SimpleDOM wenn der tree "einfach" ist

(file_get_contents() sollte arbeiten "LI" mit class "pager-last" - heraussuchen dann parsen (vermutlich $pl_node->firstChild) und dann die Seitennummer heraussuchen;

- pages ( im Moment sehe ich 288 Seiten - voller Daten).

Danach durch die Seiten loopen indem ich sie lade mit file_get_contents():

  • nach den DIV elementen sehen die mit class "ey_inner_block" beginnen.
  • diese sammeln mit saveHTML() und als mini-Dokumente innerhalb einer Loop bearbeiten und nach <P>'s, <I>'s gucken;

... ich hab auch mal einen kleinen Test mit Python und BeautifulSoup angestellt:

Code:
import requests
from bs4 import BeautifulSoup

url = 'https://europa.eu/youth/volunteering/organisations_en#open'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'lxml')
print(soup.find('title').text)
block = soup.find('div', class_="eyp-card block-is-flex")
Test usage,site have blocks with info,here some on first block.
Python Code: (Double-click to select all)


European Youth Portal

Code:
block.a
<a href="/youth/volunteering/organisation/48592_en" target="_blank">"Academy for Peace and Development" Union</a>
    block.a.text
'"Academy for Peace and Development" Union'

    block.select_one('div > div > p:nth-child(9)')
<p><strong>PIC:</strong> 948417016</p>
    block.select_one('div > div > p:nth-child(9)').text
'PIC: 948417016'

...müsste dazu auch noch mehr in BeautifulSoup einlesen;
- die Quelltextanzeige im Browser mit der Anzeige im Inspector (strg+umschalt+i) lässt eine erste Klärung und einen ersten Ansatz zu.

hab mit bs4 noch nicht sehr viel gemacht, ich werde mal den quickstart guide hier genauer ansehen
siehe https://www.crummy.com/software/BeautifulSoup/bs4/doc/

Und nachsehen welche einzelnen Elemente hier als Attribut aufrufbar sind.


Hast Du vllt. noch einen Tipp für den PHP bzw. BS4-Ansatz?


Viele Grüße
Tarifa ;)
 
Ja also wenn du Kontakt mit den Betreibern hättest - die Benutzen offensichtlich Drupal, da könnten sie Dir einen Rest-Endpoint einrichten, wie hier beschrieben, wo die Daten als JSON fertig liegen ohne den DOM Selektionen.

Da sich Seiten naturgemäß in 1-2 Jahren wieder ändern sind bei solchen Aufrufen immer wieder Nacharbeiten nötig, wenn sich die HTML Struktur ändert. Anbieter alternativer Youtube-Apps können ein Lied davon singen.

Mit Python und BeautifulSoup kenn ich mich nicht aus, bin eher aus der WordPress Ecke bzw Templates aller Art und Sprache, hauptsächlich HTML/CSS/JS und DB Daten fischen.

Also mit PHP geht das bestimmt wie aber auch in 20 anderen Sprachen.

Die "semantische" Klasse ist "eyp-card". Auf die würde ich mich konzentrieren.

Beispiel:
PHP:
function get_eyp_cards_data(){
  $dom = new DomDocument();
  $my_cards = array();

  if ( $dom->load('https://europa.eu/youth/volunteering/organisations_en') ) { // true or false https://www.php.net/manual/en/domdocument.loadhtml.php
    $domx = new DOMXpath($dom);
    $eyp_cards = $domx->query('div[contains(@class,"eyp-card")]'); // returns DOMNodeList https://www.php.net/manual/en/class.domnodelist.php

    if ( $eyp_cards->length > 0 ) { // length IS a property of DOMNodeList. works but looks a bit JSy 
      foreach ( $eyp_cards as $eyp_card ) {
        // Debug: echo '<pre>', var_dump($eyp_card), '<pre>';
        $my_cards[] = array(
          'title' => $eyp_card->getElementsByTagName('h5')->item(0)->nodeValue,
          'content' => $eyp_card->firstChild->nodeValue, // includes title
        );
      }
    }
  }
  return !empty($my_cards) ? $my_cards : false;
}

$my_cards = get_eyp_cards_data();

das war jetzt eher eine fingerübung und hab ich nicht getestet oder irgendwo ausgeführt.

contains() Selektor Referenz

Edit: jetzt hab ich das mit den Farben gecheckt.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: tarifa
Hallo und guten Tag,


Vielen Dank für die fortgesetzte Hilfe. Danke auch für die sehr wertvollen Links zu dem Thema
- dem Ansatz mit dem REST-API unter Drupal die Daten in JSON zu bekommen;
https://hackernoon.com/how-to-send-the-json-data-from-a-drupal-8-site-306145e5f5a1



Werde mich am Wochenende Mal drum kümmern. Du hast mir wirklich sehr sehr gut weitergeholfen;

Die "semantische" Klasse ist "eyp-card". Auf die würde ich mich konzentrieren.

Dir nochmals vielen Dank

Viele Grüße

Tarifa ;)
 
Zuletzt bearbeitet:

Ähnliche Themen

Zurück
Oben