Indizierung von HTML-Dateien in einem Verzeichnis (primitive Version eines Spiders)
Dieses Script durchforstet alle Dateien in einem Verzeichnis samt aller untergeordneten Ordner. Dabei sucht es nach HTML-Dateien und liest die darin enthaltenen Informationen (Header, Text) aus. Zur Datenspeicherung wird eine MySQL-Datenbank benötigt. Zudem basiert das Script auf der Nutzung des Linux Befehls FIND und funktioniert daher ausschließlich auf einem Webserver mit dem freien Betriebssystem. Durch die Einbindung als täglicher CRON-Job kann das Script automatisch den Inhalt einer (statischen) Website erfassen.
Auf die MySQL-Tabelle können natürlich Volltextsuchanfragen gemacht werden. Daher lässt sich mit diesem Skript recht einfach eine Volltextsuche innerhalb einer Website realisieren.
spider.php (PHP 4.0)
Dieses Skript ist darauf ausgelegt, dass es als Cron-Job zum Beispiel jede Nacht aufgerufen wird. Es liest zunächst die Metaheader und den Titel der Dokumente aus. Nur wenn ein Titel vorhanden ist, werden die Daten aus dem Dokument in der Datenbank gespeichert. Alle doppelten Einträge, HTML-Formatierung o.ä. werden vorher entfernt.
Wichtig: Dieses Skript geht davon aus, dass es auf einem Linux Server ausgeführt wird, da der Shell-Befehl "FIND" zur Abfrage der vorhandenen Dateien verwendet wird. Leider muss für das Skript auch der Parameter SAFE_MODE in der PHP.INI auf OFF gesetzt werden, da PHP sonst einen Zugriff auf "FIND" und die HTML-Dateien nicht zulässt.
Sollte jemand eine Idee für eine bessere Abfrage aller Unterverzeichnisse haben, kann sich die Person gerne bei mir melden!
Der Programmcode kann auch direkt als Textdatei heruntergeladen werden.
#! /usr/bin/php -q <?php
/* This program is free software; you can redistribute it. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Stefan Plogmann, comp@plogmann.net Version 1.0 Copyright (c) 2002 by Stefan Plogmann */
/* Konfigurationseinstellungen */
/* Legt fest, welche Dateiendungen beachtet werden sollen */
$conf_files=array(php,html,htm);
/* Legt fest, welche Unterverzeichnisse nicht mit durchsucht werden sollen */
$conf_ignorepath=array("/style/","/inc/","/nav/","/vorlagen/");
/* Basisverzeichnis (in der Regel wwwroot des Apache Servers),
das mit allen Unterverzeichnissen durchsucht werden soll */
$conf_basedir="/usr/httpd/htdocs/";
$dblink=DBVerbindung();
function DBVerbindung() {
/* FESTLEGUNG DER RAHMENBEDINGUNGEN */
$db_location="localhost";
$db_user="DB_USERNAME";
$db_pass="DB_PASSWORT";
$db_name="datenbank";
/* DATENBANKVERBINDUNG WIRD AUFGEBAUT */
$link = mysql_pconnect($db_location,$db_user,$db_pass) or die ("Datenbankconnect nicht moeglich");
mysql_select_db($db_name, $link) or die ("Datenbank nicht gefunden");
return $link;
}
function QueryDB($query,$link) {
$askresult = mysql_query($query, $link);
$askerror = mysql_error($link);
if ($askerror!="") { echo "Datenbankfehler: ".$askerror; stop; }
return $askresult;
}
function GetTitle($string) {
preg_match("|<title[^>]*>(.*)</title>|siU", $string, $var);
return $var[1];
}
function SpiderFile($file) {
/* Die Datei wird ausgelesen */
$file_link=fopen($file[full],"r");
$contents=fread($file_link,$file[size]);
fclose($file_link);
$title=GetTitle($contents);
if (!empty($title)) {
/* Die Header-Daten werden ausgelesen */
$meta_tags=@get_meta_tags($file[full]);
$data[title]=$title;
$data[description]=$meta_tags[description];
$data[keywords]=$meta_tags[keywords];
$data[size]=$file[size];
$data[time]=$file[time];
$data[name]=$file[name];
$data[path]=$file[path];
/* Der Content im Document wird gefiltert */
$contents=strip_tags($contents);
$contents=str_replace("\n", " ", $contents);
$contents=str_replace(" ", " ", $contents);
$contents=stripcslashes($contents);
$contents=htmlspecialchars($contents, ENT_QUOTES);
$contents_array=explode(" ",$contents);
array_unique($contents_array);
$data[body]=implode(" ",$contents_array);
}
return $data;
}
function SetQuery($data) {
$string="stamp=NOW(), name='".$data[name]."', path='".$data[path]."',
size='".$data[size]."', time='".$data[time]."', title='".$data[title]."',
description='".$data[description]."', keywords='".$data[keywords]."', body='".$data[body]."'";
return($string);
}
$stat_start=date("Y F j, H:i:s");
$stat_start_stamp=date("YmdHis");
/* Lädt alle Dateinamen in ein Array und Sammelt Basisinformationen über die Datei */
foreach($conf_files as $var_files) {
$result_string=shell_exec("find ".$conf_basedir." -name \"*".$var_files."\" -depth -type f -print");
$var_array=explode("\n", $result_string);
foreach($var_array as $var_string) {
$status="OK";
foreach($conf_ignorepath as $ignorepath) {
if(strpos($var_string,$ignorepath)>0) { $status="NotOK"; }
}
if ($status=="OK") { $result_array[]=$var_string; }
}
foreach($result_array as $var_string) {
$file[full]=$var_string;
$file[name]=basename($var_string);
$file[path]=substr(dirname($var_string),strlen($conf_basedir)-1);
$file[size]=filesize($var_string);
$file[time]=filectime($var_string);
if($file[name]!="" and $file[size]>0 and $file[time]>0) { $files[]=$file; }
}
}
/* Die Statistik-Zähler werden einfach mal alle angelegt */
$stat_found=count($files);
$stat_new=0;
$stat_updated=0;
$stat_unchanged=0;
$stat_deleted=0;
$stat_removed=0;
$stat_spidered=0;
foreach($files as $file) {
/* Für jede gefundene Datei wird nun geschaut, ob schon in der DB ein Datensatz
dafür angelegt wurde */
$result_db=QueryDB("SELECT file,size,time FROM spider WHERE name='".$file[name]."'
AND path='".$file[path]."'",$dblink);
$row_old=mysql_fetch_array($result_db);
if(!empty($row_old)) {
/* Sollte ein Datensatz vorhanden sein... */
if($row_old[size]==$file[size] and $row_old[time]==$file[time]) {
/* Sollte sich die Datei seit der letzten Indizierung nicht verändert haben... */
$result_db=QueryDB("UPDATE spider SET stamp=NOW() WHERE file='".$row_old[file]."'",$dblink);
$stat_unchanged++;
} else {
/* Sollte sich die Datei seit der letzten Indizierung verändert haben... */
$data=SpiderFile($file);
$stat_spidered++;
if(!empty($data)) {
/* Können Metadaten ausgelesen werden, werden diese gespeichert */
$result_db=QueryDB("UPDATE spider SET ".SetQuery($data)." WHERE file='".$row_old[file]."'",$dblink);
$stat_updated++;
} else {
/* Ist die Datei nicht lesbar, wird der Datensatz gelöscht */
$result_db=QueryDB("DELETE FROM spider WHERE file='".$row_old[file]."'",$dblink);
$stat_deleted++;
}
}
} else {
/* Sollte noch kein Datensatz vorhanden sein... */
$data=SpiderFile($file);
$stat_spidered++;
if(!empty($data)) {
/* ... und die Datei lesbar sein, wird der Datenatz geschrieben */
$result_db=QueryDB("INSERT INTO spider SET ".SetQuery($data),$dblink);
$stat_new++;
}
}
}
/* Löschen aller alten Datensätze */
$result=QueryDB("DELETE FROM spider WHERE stamp<'".$stat_start_stamp."'",$dblink);
$stat_removed=mysql_affected_rows($dblink);
/* Ausgabe der statischen Informationen */
$stat_end=date("Y F j, H:i:s");
echo "INDIZIERUNG VON DOKUMENTEN\n";
echo "Ergebnis der Indizierung des Verzeichnisses ".$conf_basedir."\n\n";
echo "Startzeit: ".$stat_start."\n";
echo "Endzeit: ".$stat_start."\n";
echo "Verarbeitete Dateien: ".$stat_found."\n";
echo "Neue Datensaetze: ".$stat_new."\n";
echo "Aktualisierte Datensaetze: ".$stat_updated."\n";
echo "Unveraenderte Datensaetze: ".$stat_unchanged."\n";
echo "Geloeschte Datensaetze: ".$stat_deleted."\n";
echo "Entfernte Datensaetze: ".$stat_removed."\n";
echo "Geprüfte Dateien: ".$stat_spidered."\n";
?>
SQL-Befehl für Erstellung der benötigten Tabelle
Den folgenden Befehl kann man einfach mit Hilfe von phpMyAdmin ausführen. Es wird eine Tabelle mit dem Namen "spider" angelegt.
# phpMyAdmin MySQL-Dump # version 2.2.0rc3 # http://phpwizard.net/phpMyAdmin/ # http://phpmyadmin.sourceforge.net/ (download page) # # Host: localhost # Erstellungszeit: June 6, 2002, 3:06 pm # Server Version: 3.23.37 # PHP Version: 4.0.6 # Datenbank : datenbank # --------------------------------------------------------
# # Tabellenstruktur für Tabelle 'spider' #
CREATE TABLE `spider` ( `file` int(10) unsigned NOT NULL auto_increment, `stamp` timestamp(14) NOT NULL, `name` varchar(255) NOT NULL default '', `path` varchar(255) NOT NULL default '', `size` int(11) NOT NULL default '0', `time` bigint(11) default NULL, `title` text NOT NULL, `description` text, `keywords` text, `body` text NOT NULL, PRIMARY KEY (`file`), UNIQUE KEY `file` (`file`), KEY `file_2` (`file`), KEY `name` (`name`), KEY `path` (`path`) ) TYPE=MyISAM;
CronJob
Nach erfolgreichem Test der Programmes kann man das Skript in die CRONTAB-Tabelle mit aufnehmen. Diese befindet sich in der Regel unter /etc/crontab.Bei diesem Beispiel wird der CronJob jeden Morgen um 3:30 Uhr ausgeführt. Als User habe ich wwwrun gewählt. Dies sollte man aber jeweils den Bedürfnissen des eigenen Servers anpassen.
03 3 * * * wwwrun /pfad/spider.php
Haftungshinweis: Trotz sorgfältiger inhaltlicher Kontrolle übernehme
ich keine Haftung für die Inhalte externer Links. Für den
Inhalt der verlinkten Seiten sind ausschließlich deren Betreiber
verantwortlich.
Besuchen Sie auch meine Bildergalerie unter
gallery.plogmann.net.
© Stefan Plogmann, 1996-2008
