kostenloser Webspace werbefrei: lima-city


Webseiten Analysieren

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    h***********r

    Hallöchen ;D
    Mir war mal wieder langweilig, da habe ich mir hier ein kleines System zum mehr oder weniger Analysieren von Websites gebastelt. Den Originalcode habe ich ausm Netz (Finde gerade nicht wo genau), habe da ein wenig um und rein gebastelt. Ich finde mein Code ist evtl nicht gerade der beste oder effizienteste, evtl findet ihr was was man verbessern kann. Derzeit bekommt man damit zwischen 1 und ~250 Seiten pro Sekunde durch.
    Hier ist so ein ungefährer überblick was der Code machen soll:

    Überprüfen ob noch Startpunkte im Pool verfügbar sind
       {Wenn nein diese Tabelle zurücksetzen, die Startpunkte aus Tabelle 3 laden, rückwärts sortieren, einsetzen in Tabelle 2 und Tabelle 3 dann zurücksetzen}
    URL für Startpunkt aus Tabelle 2 hohlen, aus Tabelle 2 löschen in Tabelle 3 setzen
    Einige Werte für das hohlen der Daten festlegen, header, Laufzeit, arrays
    Hier arbeitet der Webcrawler
    Kucken ob URL bereits in der DB war, dann erneuern oder erstellen.

    Und hier ist der Code. Name der Tabellen und Verbindung zur DB steht in sql.php.
    <?php
    include './sql.php';
    sturl();
    
    function sturl(){
    global $host, $user, $db, $pass, $table2, $table3, $currentdate;
    //Check
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table2)";
    $resultu = $mysqli->query($select);
    if (mysqli_num_rows($resultu) == 0){
    //RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//
    //Datenbank 1 zurücksetzen
    $mysqli = new mysqli($host, $user, $pass, $db);
    $format = "TRUNCATE TABLE $table2)";
    $result0 = $mysqli->query($format);
    
    //Datenbank 2 laden:
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table3)";
    $result1 = $mysqli->query($select);
    while($row = $result->fetch_array())
    {
    $rows[] = $row;
    $urls[$x]= $row[0];
    $x = $x+1;
    }
    //Umkehren
    $reurl = array_reverse($url);
    $x = 0;
    
    while ($x<=sizeof($reurl)){
    //Einsetzen in DB 1
    	$mysqli = new mysqli($host, $user, $pass, $db);
    	$insert = "INSERT INTO $table2 (url) VALUES ('$reurl[$x]')";
    	$result2 = $mysqli->query($insert);
    	$x = $x+1;
    }
    	
    	
    //Datenbank 2 zurücksetzen
    $mysqli = new mysqli($host, $user, $pass, $db);
    $format = "TRUNCATE TABLE $table3)";
    $result3 = $mysqli->query($format);
    }
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Get
    $mysqli = new mysqli($host, $user, $pass, $db);
    $view = "SELECT url FROM $table2";
    $result = $mysqli->query($view);
    $var = mysqli_fetch_array($result);
    $url = $var[0];
    //Del
    $mysqli = new mysqli($host, $user, $pass, $db);
    $view = "DELETE FROM $table2 WHERE url='$url'";
    $result = $mysqli->query($view);
    //Set
    $mysqli = new mysqli($host, $user, $pass, $db);
    $view = "INSERT INTO $table3 (url) VALUES ('$url')";
    $result = $mysqli->query($view);
    procst($url);
    }
    function procst($url){
    $runtime  = 2;//Time Limit der Suche
    
    //AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##AUSFÜHREN##
    
    //Bezeichnung des Crawlers
    $name_crawl = "Mr-Horstexplorer/1.04\n";
    $currentdate = date('Y.d.m'); //Setzen des aktuellen Datums im yyy.dd.mm Format
    set_time_limit($runtime*60); //Script soll nur n Minuten lang arbeiten, dann wird script mit anderer URL neu gestartet. // $untime in Minuten angeben
    $already_crawled = array();
    $crawling = array();
    follow_links($url);
    
    }
    //FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##FUNKTIONEN##
    function follow_links($url) {
    	global $already_crawled;
    	global $crawling;
    	global $name_crawl;
    	$options = array('http'=>array('method'=>"GET", 'headers'=>$name_crawl));
    	$context = stream_context_create($options);
    	$doc = new DOMDocument();
    	@$doc->loadHTML(@file_get_contents($url, false, $context));
    	$linklist = $doc->getElementsByTagName("a");
    	foreach ($linklist as $link) {
    		$l =  $link->getAttribute("href");
    		
    		if (substr($l, 0, 1) == "/" && substr($l, 0, 2) != "//") {
    			$l = parse_url($url)["scheme"]."://".parse_url($url)["host"].$l;
    		} else if (substr($l, 0, 2) == "//") {
    			$l = parse_url($url)["scheme"].":".$l;
    		} else if (substr($l, 0, 2) == "./") {
    			$l = parse_url($url)["scheme"]."://".parse_url($url)["host"].dirname(parse_url($url)["path"]).substr($l, 1);
    		} else if (substr($l, 0, 1) == "#") {
    			$l = parse_url($url)["scheme"]."://".parse_url($url)["host"].parse_url($url)["path"].$l;
    		} else if (substr($l, 0, 3) == "../") {
    			$l = parse_url($url)["scheme"]."://".parse_url($url)["host"]."/".$l;
    		} else if (substr($l, 0, 11) == "javascript:") {
    			continue;
    		} else if (substr($l, 0, 5) != "https" && substr($l, 0, 4) != "http") {
    			$l = parse_url($url)["scheme"]."://".parse_url($url)["host"]."/".$l;
    		}
    		if (!in_array($l, $already_crawled)) {
    				$already_crawled[] = $l;
    				$crawling[] = $l;
    				
    				get_details($l);
    		}
    	}
    	array_shift($crawling);
    	foreach ($crawling as $site) {
    		follow_links($site);
    	}
    }
    function get_details($url) {
    	global $name_crawl;
    	$options = array('http'=>array('method'=>"GET", 'headers'=>"User-Agent: ".$name_crawl));
    	$context = stream_context_create($options);
    	$doc = new DOMDocument();
    	@$doc->loadHTML(@file_get_contents($url, false, $context));
    	$title = $doc->getElementsByTagName("title");
    	$title = $title->item(0)->nodeValue;
    	$description = "";
    	$keywords = "";
    	$metas = $doc->getElementsByTagName("meta");
    	for ($i = 0; $i < $metas->length; $i++) {
    		$meta = $metas->item($i);
    		if (strtolower($meta->getAttribute("name")) == "description")
    			$description = $meta->getAttribute("content");
    		if (strtolower($meta->getAttribute("name")) == "keywords")
    			$keywords = $meta->getAttribute("content");
    	}
    //
    $tile = str_replace("\n", "", $title);
    $description = str_replace("\n", "", $description);
    $keywords = str_replace("\n", "", $keywords);
    
    //Einfügen in Datenbank bzw Erneuern.
    global $host, $user, $db, $pass, $table, $currentdate;
    $mysqli = new mysqli($host, $user, $pass, $db);
    $view = "SELECT * FROM $table WHERE url='$url'";
    $result = $mysqli->query($view);
    
    if (mysqli_num_rows($result) == 1) {
    
    //Eintrag updaten.
    $mysqli = new mysqli($host, $user, $pass, $db);
    $insert = "UPDATE $table SET last_refresh='$currentdate', title='$title', description = '$description', keywords='$keywords' WHERE url='$url'";
    $result = $mysqli->query($insert);
    }
    else{
    //Eintrag erstellen.
    $mysqli = new mysqli($host, $user, $pass, $db);
    $insert = "INSERT INTO $table (url, title, description, keywords, last_refresh) VALUES ('$url','$title','$description','$keywords', '$currentdate')";
    $result = $mysqli->query($insert);
    }
    }

    Das Datum der letzen Aktualisierung kommt deswegen hin um nicht mehr gültige Links nach 3 Wochen auszusortieren.

    Beitrag zuletzt geändert: 15.12.2017 8:58:41 von horstexplorer
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. fussballturnier

    fussballturnier hat kostenlosen Webspace.

    Du Speicherst die komplette Webseite in eine DB oder habe ich das falsch verstanden? Müsste mir das mal ansehen in einer ruhigen Minute.
  4. Autor dieses Themas

    h***********r

    Nein, gespeichert werden nur die Zugriffsdaten (Uhrzeit, URL), der Titel der jeweiligen Seite und gegebene Content Informationen.


    Beitrag zuletzt geändert: 14.12.2017 21:27:22 von horstexplorer
  5. mein-wunschname

    mein-wunschname hat kostenlosen Webspace.

    OT: Wenn du schon deinen Code so formatierst, dass man ihn denkbar schlecht lesen kann, dann posten ihn doch hier wenigstens so:
    <?php
    include './sql.php';
    sturl();
    
    function sturl(){
    global $host, $user, $db, $pass, $table2, $table3, $currentdate;
    //Check
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table2)";
    $resultu = $mysqli->query($select);
    if (mysqli_num_rows($resultu) == 0){
    //RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//
    //Datenbank 1 zurücksetzen
    $mysqli = new mysqli($host, $user, $pass, $db);
    $format = "TRUNCATE TABLE $table2)";
    $result0 = $mysqli->query($format);
    
    //Datenbank 2 laden:
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table3)";
    $result1 = $mysqli->query($select);
    while($row = $result->fetch_array())
    {
    $rows[] = $row;
    $urls[$x]= $row[0];
    $x = $x+1;
    }


    Das sind nur 4 Zeichen Zusatzaufwand.
  6. Autor dieses Themas

    h***********r

    mein-wunschname schrieb:
    OT: Wenn du schon deinen Code so formatierst, dass man ihn denkbar schlecht lesen kann, dann posten ihn doch hier wenigstens so:
    <?php
    include './sql.php';
    sturl();
    
    function sturl(){
    global $host, $user, $db, $pass, $table2, $table3, $currentdate;
    //Check
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table2)";
    $resultu = $mysqli->query($select);
    if (mysqli_num_rows($resultu) == 0){
    //RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//RESET//
    //Datenbank 1 zurücksetzen
    $mysqli = new mysqli($host, $user, $pass, $db);
    $format = "TRUNCATE TABLE $table2)";
    $result0 = $mysqli->query($format);
    
    //Datenbank 2 laden:
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table3)";
    $result1 = $mysqli->query($select);
    while($row = $result->fetch_array())
    {
    $rows[] = $row;
    $urls[$x]= $row[0];
    $x = $x+1;
    }


    Das sind nur 4 Zeichen Zusatzaufwand.

    Okay die Funktion kannte ich nicht nicht ;)
  7. Hallo Horst,

    unabhängig von den Formatierungsproblemen, was ist genau dein Ziel damit? Willst du einen bestimmten Content einer Webseite auslesen?
    Also ich hab mir auch mal ein Script geschrieben um Amazon Artikelnummern aus zu lesen, finde es nur grad nicht mehr! Ist aber auch schon fast 10 Jahre her und habs seitdem nicht mehr wirklich genutzt :-(

    Aber man liest ja andere Seiten nur aus um etwas davon zu nutzen oder speichern und ggf. zu analysieren. Also, was bezweckst du damit etwas konkreter?

  8. Autor dieses Themas

    h***********r

    Oh genaue Ziele :D
    Eigentlich soll es erstmal nur weg speichern was es findet. Danach hatte ich mir überlegt das nach Inhalten durchsuchen zu können. Wie das aber aussehen soll habe ich mir noch nicht wirklich überlegt.
    Problematisch ist das nicht alle Webseiten Content in Meta Tags schreiben. Somit bleibt das ganze meist leer. Da könnte man ggf irgendwie nachbessern.
    Sonnst ist sehr viel mit SQL gearbeitet. Evtl kann man dort etwas zusammenfassen.
  9. Also nur um es richtig zu verstehen, du willst mit der Seite den Textnhalt komplett wegspeichern?

    Dann müsste es ganz einfach gehen, indem du einfach die komplette Seite liest und alles zwischen den "<" und ">" Tags löschst. Am Ende fügst du es zusammen und speicherst es ab.

    Um Menus etc zu ignorieren musst du halt spezifische Tags noch suchen, die in Frage kommen könnten um diese zu ignorieren. Aber da geht es schon eher drum, dass man dann Detailarbeit machen muss um zu gewährleisten, dass sinnlose Inhalte ignoriert werden.

    Gibt zwar wenig bis keinen Sinn für mich aber so kannst du einfach und schnell Seitenkontexte einfach lesen und speichern!

    Wie gestaltest du die Suche der Webseiten? gibst du die Seiten vor, die durchsucht werden sollen oder wie hast du dir das gebaut, dass Seiten gesucht werden?
  10. Autor dieses Themas

    h***********r

    Ganz so meinte ich das nicht.
    Derzeit werden (und sollen) nur neben dem Titel der Webseite die Content Daten aus dem Meta Tag gespeichert werden. Also so ala Stichwörter über den Seiteninhalt
    <meta content="Äpfel,Birnen, Bananen" />

    Würde ich die ganze Seite speichern würde die DB größe explodieren und das suchen nochmal deutlich länger dauern :)
    Leider ist nur in ca 1/20 aller Seiten solch ein Content gesetzt, da müsste man sich ggf mit Hilfssystemen den Inhalt erarbeiten z.bsp an Überschriften. (Evtl baue ich das noch irgendwie ein)

    Wie meinst du das mit dem Suche der Webseiten? Wie ich die laden um sie zu analysieren?

    An sich gebe ich eine Seite an wo die Analyse starten soll. Z.bsp Lima-City.de
    (Diese Seiten werden nach und nach aus einem Pool aus einer DB geladen, ist der Pool leer wird er wieder zurück gesetzt.)
    Der webcrawler arbeitet sich nun n Minuten (2) an allen Verlinkungen die es auf den Seiten und den nächsten findet weiter. Somit kommt man Recht gut an viele Informationen die die Seite anbietet ran. Natürlich wird auch viel müll mitgenommen.
    Den Startwert gibt es um Seiten einfacher auch erneut auslesen zu können fals sich der Inhalt ändern sollte. Datensätze die dann nach 3Wochen (3 Suchdurchläufen) nicht mehr aktualisiert wurden werden gelöscht.
    So die Theorie.
    (Ich kucke Mal ob ich da die Ausgabe auch ohne das DB Zeugs hin bekomme falls sich das jemand ansehen will. Link kommt dann hier rein)

    Beitrag zuletzt geändert: 17.12.2017 12:06:14 von horstexplorer
  11. Ah OK, naja stimmt, die Meta daten pflegen die wenigsten! Vor allem Privatpersonen verzichten oft darauf. Professionelle Seiten setzen das meistens aber auch nicht immer!

    Hast du den Aufruf über einen Cronjob gesteuert?

    Nach wie vor erschließt sich mir zwar der Sinn noch nicht so wirklich aber ich hoffe dass du diesen für dich erkannt hast!

    Jetzt nochmal ne blöde Frage, wolltest du Hilfe bei deinem Ursprungspost? Willst du das Auslesen optimieren oder eher Unterstützung um es zu optimieren?

  12. Autor dieses Themas

    h***********r


    Hast du den Aufruf über einen Cronjob gesteuert?

    Nach wie vor erschließt sich mir zwar der Sinn noch nicht so wirklich aber ich hoffe dass du diesen für dich erkannt hast!

    Jetzt nochmal ne blöde Frage, wolltest du Hilfe bei deinem Ursprungspost? Willst du das Auslesen optimieren oder eher Unterstützung um es zu optimieren?

    Ja das ganze wird dann später über einen Cron gestartet.
    An sich ging es mir um Code Optimierung, vorallem bei den Datenbankabfragen am Anfang, aber auch noch das hinzufügen des Auslesens der Überschriften der Seite, fals es keine Content Tags geben sollte (Also alle h Tags)
    Hier mal so zum Test der Ausgabe
    http://horstexplorer.lima-city.de/LinkTest/test.php

    Beitrag zuletzt geändert: 17.12.2017 16:44:32 von horstexplorer
  13. horstexplorer schrieb:
    An sich ging es mir um Code Optimierung, vorallem bei den Datenbankabfragen am Anfang

    Ein Anfang wäre: Nicht für jede Abfrage eine neue Verbindung auf machen.

    aber auch noch das hinzufügen des Auslesens der Überschriften der Seite, fals es keine Content Tags geben sollte (Also alle h Tags)

    Die entsprechenden Methoden nutzt du doch schon. Musste nur den Aufruf entsprechend anpassen.

    Zur Übersichtlichkeit kann ich dir nur (wieder) sagen: Formatiere anständig und schau dir das OOP-Konzept an.
  14. Autor dieses Themas

    h***********r

    Okay.
    Das mit den Überschriften war tatsächlich einfacher als gedacht:
    $uschrift = $doc->getElementsByTagName("h1");
        $uschrift = $uschrift->item(0)->nodeValue;

    Einfach hinzugefügt, läuft, freut mich :D

    Das Mysql kann also auch so aussehen?:
    $mysqli = new mysqli($host, $user, $pass, $db);
    $select = "SELECT url from $table2)";
    $resultu = $mysqli->query($select);
    if (mysqli_num_rows($resultu) == 0){
    //Datenbank 1 zurücksetzen
    $format = "TRUNCATE TABLE $table2)";
    $result0 = $mysqli->query($format);

    Also dass man nur einmal die Verbindung öffnen muss.
    (Muss man das in jeder Funktion erneut machen oder reicht einmal ganz am Anfang und $mysqli als global?)

    Hier ist nochmal der Code in Aktion, ohne DB
    http://horstexplorer.lima-city.de/LinkTest/test.php
    //Bei Lima-City.de als Startpunkt sind es gerade 916 Seiten in 3Min -> 5 /s

    //Gerade gesehen, Facebook z.bsp meint "Browser aktualisieren". WIe kommt man denn da drum...

    Beitrag zuletzt geändert: 17.12.2017 17:08:12 von horstexplorer
  15. horstexplorer schrieb:
    Das Mysql kann also auch so aussehen?:
    [...]
    Also dass man nur einmal die Verbindung öffnen muss

    Freilich. Wenn dir irgendein Tutorial oder so sagt, es wäre notwenig nach jeder Query eine neue Verbindung aufzumachen kannst du das direkt in die Tonne kloppen.
    (Muss man das in jeder Funktion erneut machen oder reicht einmal ganz am Anfang und $mysqli als global?)

    Warum solltest du das in jeder Funktion einzeln machen müssen? Der Geltungsbereich ist der selbe wie bei anderen Variablen.
    Ich bringe hier nochmal OOP ins Spiel, dann kannste die Datenbank-Dinge auch schön und easy als Singleton umsetzen.


    Gerade gesehen, Facebook z.bsp meint "Browser aktualisieren". WIe kommt man denn da drum...

    Einfach einen passenden User-Agent bei den Anfragen mit senden
  16. Autor dieses Themas

    h***********r

    muellerlukas schrieb:
    horstexplorer schrieb:
    Das Mysql kann also auch so aussehen?:
    [...]
    Also dass man nur einmal die Verbindung öffnen muss

    Freilich. Wenn dir irgendein Tutorial oder so sagt, es wäre notwenig nach jeder Query eine neue Verbindung aufzumachen kannst du das direkt in die Tonne kloppen.
    (Muss man das in jeder Funktion erneut machen oder reicht einmal ganz am Anfang und $mysqli als global?)

    Warum solltest du das in jeder Funktion einzeln machen müssen? Der Geltungsbereich ist der selbe wie bei anderen Variablen.

    Habe das immer wieder Copy-Paste eingefügt und deswegen nicht drüber nach gedacht wie es aussehen kann :D
    Ich bringe hier nochmal OOP ins Spiel, dann kannste die Datenbank-Dinge auch schön und easy als Singleton umsetzen.


    Gerade gesehen, Facebook z.bsp meint "Browser aktualisieren". WIe kommt man denn da drum...

    Einfach einen passenden User-Agent bei den Anfragen mit senden

    OOP ist mit von Java noch immer etwas gruselig, deswegen traue ich mich da erstmal nicht dran.
    Wie geht des das mit dem User-Agent?
    Hätte überlegt das es irgendwie mit
    $_SERVER['HTTP_USER_AGENT'] = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36;

    funktionieren könnte, bezweifle ich aber trotzdem :D
    //Habe gerade nachgelesen dass das mit
    ini_set('user_agent', 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11');

    angeblich funktioniert. Getestet habe ich's noch nicht.
    //Scheinbar geht es :)

    Beitrag zuletzt geändert: 17.12.2017 22:52:57 von horstexplorer
  17. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!