Oftmals möchte man die auf Webseiten angegebenen eMail-Adressen automatisiert auslesen, z.B. um eine größere Menge Ansprechpartner für einen Linktausch zu finden oder auch einfach nur, um möglichst schnell möglichst viele SPAMbare Adressen zu erhalten. Das lässt sich mit Regulären Ausdrücken einfach realisieren. Dies soll keine Aufforderung zum Spammen sein, es geht hier lediglich um ein Anwendungsbeispiel. SPAM nervt uns sicher genauso stark wie Sie.
Vorüberlegungen
Vorab müssen wir uns überlegen, was wir genau machen wollen. Wir wollen den Inhalt einer URL auslesen und im Text enthaltene eMail-Adressen extrahieren. Die gesuchten Adressen können entweder als Verweis oder als normaler Text auftreten - was hier aber quasi keine Rolle spielt.
Für eMail-Adressen gibt es genau Vorgaben, welche Zeichen in ihnen Verwendung
finden dürfen. Ein kurzer Blick in die RFC 2822 sagt uns,
dass in dem Teil vor dem @ (dem sogenannten local-part)
nur Buchstaben, Ziffern und folgende Sonderzeichen erlaubt sind:
.!#$%&'*+-/=?^_`{|}~. Laut Definition
dürfen noch weitere Sonderzeichen vorkommen, die entweder in "
eingeschlossen oder durch einen Backslash maskiert werden müssen.
Der Teil nach dem @ (der sogenannte domain-part)
darf nur aus Buchstaben, Ziffern und den Zeichen -
und . bestehen.
Ob es sich bei den extrahierten Adressen wirklich um gültige eMail-Adressen handelt, ließe sich auch feststellen - indem man z.B. eine entsprechende Anfrage an den jeweiligen Server stellt - dies soll hier aber nicht das Thema sein.
Ein wenig Realismus
Bei genauerer Betrachtung fallen in oben stehender Definition ein paar Rattenschwänze auf. Viele der im local-part erlaubten Zeichen kommen in 99% aller eMail-Adressen gar nicht vor, im Gegenteil: Würden wir sie als gültige Zeichen betrachten, würden wir unter Umständen mehr falsche Adressen auslesen, als uns verloren gingen, wenn wir diese seltenen Zeichen nicht beachten würden. Auf weitere Ausführungen dieses Aspektes sei hier verzichtet, da diese den Rahmen dieses Artikel sprengen würden. Ähnliche Überlegungen kann man übrigens auch für den domain-part anstellen.
Wir einigen uns also auf folgendes: Wir werden für den local-part
neben Buchstaben und Ziffern lediglich die Zeichen -,
_ und . (wobei der Punkt
weder am Ende noch am Anfang stehen darf) erlauben. Für den domain-part
legen wir folgende Konventionen fest: Er besteht aus der Domain, für die oben
genannte Regeln gelten, gefolgt von einem . und der
TLD, die im Normalfall aus mindestens zwei Buchstaben besteht.
Vorgehensweise
Um überhaupt Adressen extrahieren zu können, müssen wir erst einmal den Inhalt der jeweiligen Webseite auslesen. Dies lässt sich recht einfach mit Hilfe der PHP-Funktion file_get_contents bewerkstelligen. Damit lässt sich der Inhalt einer Datei - oder in unsere Falle - einer URL einlesen. Bitte beachten Sie dazu auch die Hinweise im PHP-Manual, manche Server erlauben das Einlesen von URLs nicht.
Auslesen der URL
Folgender Code liefert uns den gewünschten Inhalt:
<?PHP
//
// URL der Seite, die eingelesen werden soll
//
$url = 'http://nophia.de';
//
// Inhalt einlesen
//
$inhalt = file_get_contents($url);
?>
Da wir jetzt den Inhalt der Webseite haben, können wir uns überlegen, wie
der Reguläre Ausdruck aussehen muss, den wir zur Extraktion der Adressen
verwenden wollen. Wir gehen dabei Schritt für Schritt vor.
Aufstellen des grundlegenden Suchmusters
Zuerst stellen wir in groben Zügen unser Suchmuster zusammen. Es besteht
vorerst nur aus den Delimitern und dem @ in der Mitte der Adresse:
# ... @ ... #i
Da in eMail-Adressen durchaus auch Großbuchstaben vorkommen können, setzen wir
den Modifier i.
Der vordere Teil
Da wir eindeutig definiert haben, welche Zeichen in eMail-Adressen vorkommen
dürfen, fällt es uns sehr leicht, ein passendes Suchmuster aufzustellen.
Wir brauchen lediglich eine Zeichenklasse definieren, die die erlaubten Zeichen
enthält:
#[a-z0-9.\-_]@ ... #i
Eventuell in Zeichenklassen gültige Metazeichen (z.B. den Bindestrich)
müssen wir maskieren.
Da der Teil vor dem @ quasi beliebig lang sein kann,
setzen wir hinter die Zeichenklasse noch den Quantifier +. Um sicherzustellen,
dass am Anfang und am Ende des local-part kein Punkt vorkommt,
definieren wir jeweils noch eine Zeichenklasse, die alle erlaubten Zeichen
enthält, den Punkt aber ausschließt. Diese versehen wir jeweils noch mit dem
Quantifier ?, da es sonst bei kurzen Adressen zu Problemen käme.
Unser Ausdruck sieht jetzt also so aus:
#[a-z0-9\-_]?[a-z0-9.\-_]+[a-z0-9\-_]?@ ... #i
Der hintere Teil
Für den hinteren Teil können wir ähnlich vorgehen. Wir definieren wiederum eine
Zeichenklasse, die die erlaubten Zeichen enthält, gefolgt vom Quantifier +.
Dahinter folgt dann, durch einen Punkt verbunden, die Definition für die
TLD, so dass der Ausdruck jetzt so aussieht:
#[a-z0-9\-_]?[a-z0-9.\-_]+[a-z0-9\-_]?@[a-z.-]+\.[a-z]{2,}#i
Der Bindestrich in der ersten Zeichenklasse braucht nicht zusätzlich maskiert
sein, da er am Ende der Zeichenklasse steht und somit keinen Zeichenbereich definiert.
Das war es dann quasi schon, unser Regulärer Ausdruck ist damit vollständig, wir können ihn nun auf den ausgelesenen Text anwenden.
Extraktion per PHP
Den entwickelten Regulären Ausdruck können wir jetzt per PHP
auf den Text anwenden. Da wir alle eMail-Adressen extrahieren wollen,
benutzen wir preg_match_all():
<?PHP
//
// RegExp auf Inhalt anwenden
//
$results = preg_match_all('#[a-z0-9\-_]?[a-z0-9.\-_]+[a-z0-9\-_]?@[a-z.-]+\.[a-z]{2,}#i', $inhalt, $subpattern);
?>
Die Rückgabe von preg_match_all() weisen wir einer Variablen zu, um später
einen Überblick zu haben, wie viel Adressen extrahiert wurden.
Die gefundenen Adressen liegen jetzt in der Variable $subpattern in folgender
Form vor:
Array
(
[0] => Array
(
[0] => Adresse 1
[1] => Adresse 2
[2] => ...
)
)
Zur Weiterverwendung wollen wir sie jetzt noch in ein eigenes Array packen.
Wir durchlaufen also das erste Element des Rückgabe-Arrays (Index 0) per
foreach()-Schleife und fügen die Adressen dann einem neuen Array hinzu.
<?PHP
//
// Neues Array initialisieren
//
$emails = array();
//
// Rückgabe durchlaufen
//
foreach($subpattern[0] as $email) {
$emails[] = $email;
}
?>
Damit haben wir unser Ziel fast erreicht, wir müssen nur noch vorhandene Duplikate
entfernen und die extrahierten eMail-Adressen ausgeben:
<?PHP
//
// Duplikate entfernen
//
$emails = array_unique($emails);
//
// Ausgabe
//
echo '<p>Extrahierte Adressen: '.$results.'</p>';
echo '<p>Einzigartige Adressen: '.count($emails).'</p>';
echo '<pre>'.print_r($emails, TRUE).'</pre>';
?>
Viel Spaß beim Spammen.
Anmerkungen
Sowohl die Tatsache, dass die aufgerufene URL nicht erreichbar sein könnte, als auch, dass die Seite keinerlei Adressen beinhalten könnte, wurden hier ignoriert. Die Überprüfung dieser Fehler sei dem Leser überlassen. Sollten Sie einen Fehler gefunden haben oder Vorschläge oder Anregungen haben, können Sie uns das gerne mitteilen.
Vollständiger Quellcode
Hier fnden Sie den vollständigen Quellcode für dieses Beispiel:
<?PHP
//
// URL der Seite, die eingelesen werden soll
//
$url = 'http://nophia.de';
//
// Inhalt einlesen
//
$inhalt = file_get_contents($url);
//
// RegExp auf Inhalt anwenden
//
$results = preg_match_all('#[a-z0-9\-_]?[a-z0-9.\-_]+[a-z0-9\-_]?@[a-z.-]+\.[a-z]{2,}#i', $inhalt, $subpattern);
//
// Neues Array initialisieren
//
$emails = array();
//
// Rückgabe durchlaufen
//
foreach($subpattern[0] as $email) {
$emails[] = $email;
}
//
// Duplikate entfernen
//
$emails = array_unique($emails);
//
// Ausgabe
//
echo '<p>Extrahierte Adressen: '.$results.'</p>';
echo '<p>Einzigartige Adressen: '.count($emails).'</p>';
echo '<pre>'.print_r($emails, TRUE).'</pre>';
?>
Sie können den Quellcode auch als Datei herunterladen.
Um die Datei verwenden zu können, müssen sie die Dateiendung .txt entfernen - sie
wurde hier lediglich angehängt, um einen Download zu ermöglichen.
Verwandte Themen
- Anwendungsbeispiele
- Aufbau von Regulären Ausdrücken
- Delimiter
- Der Backslash
- Fehlermeldungen
- Metazeichen
- Modifier
- PHP-Funktionen
- preg_match_all()
- Quantifier
- Unterausdrücke
- Zeichenklassen
Kapitelnavigation
- Letzte Änderung: 24.07.2010, 03:39:02
- © 2003 - 2010 nophia web