Suchmaschine für die Webseite
bearbeitet von
Da die Meinungen über das Skript offenbar sehr auseinendergehen beschreibe ich ich mal, was das gezeigte Skript macht.
Erst mal die Zusammenfassung: Das Skript holt die Startseite und alle verlinkten Webseiten unterhalb der konfigurierten Domain ab, speichert diese jedoch nicht sondern schreibt die gefilterten URLs in eine Datei [sitemap.txt](https://support.google.com/webmasters/answer/183668?hl=de), die auf dem Document-Root des Webservers lesbar abgelegt wird.
Das Skript kann die Aufgabe lösen, alle Ressourcen eines dynamisch erzeugten Webauftritts zu listen. Für rein statische Webauftritte mit HTML-Dateien gäbe es performantere (weniger Last erzeugende) Wege. Aber funktionieren würde das Skript auch bei diesen.
~~~bash
#!/bin/bash
~~~
Es ist ein Bash-Skript. Also (die bash.exe gibt es inzwischen auch für Windows) faktisch nur für Linux.
~~~bash
protocol='https';
servername='example.com';
~~~
Das ist ein wichtiger Teil der Konfiguaration. Servername ist der Hostname des Webservers.
~~~bash
export LANG="de_DE.utf8";
~~~
Da die über den Fehlerkanal erfolgenden Ausgaben des Programmes wget an die eingestellte Sprache und damit auch an bestimmte Formate z.B. für das Datum gebunden sind ist es wichtig die Sprache einzustellen, da man sonst nicht sicher sein kann, welche Spracheinstellung vorgenommen wurde.
~~~
cd /tmp;
umask 077;
tmpFile=$(mktemp);
~~~
Der Skriptinterpreter wechselt in das temporäre Verzeichnis, setzt die umask auf 077. Das bedeutet, dass an den gleich angelegten Verzeichnissen und Dateien nur derjenige Benutzer Rechte bekommt, unter dem das Skript ausgeführt wird. Dann wird auch noch eine temporäre Datei angelegt, deren Pfad und Name in `$tmpfile` steht.
~~~bash
wget --delete-after -mr ${protocol}://${servername}
~~~
wget wird also benutzt und soll die abgeholten Dateien wieder löschen. wget wird angewiesen, Links im Webautritt zu folgen um wirklich alle verlinkten Ressourcen abzuholen.
~~~bash
2>&1
~~~
Die Notizen des gesprächigen `grep` erfolgen auf dem Fehlerkanal (2, StdErr), werden aber auf die Standardausgabe (1, StdOut) umgeleitet. Dies wird wegen der nachfolgenden Filter benötigt.
~~~bash
| grep -P "^--\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d-- "
~~~
In den Ausgaben finden sich Zeilen, welche postulieren, wann welche Ressource angefordert wurde. Diese haben als eindeutiges Merkmal den Zeitpunkt mit Datum im ISO-Format. Mit dem Perl-kompatiblen regulären Ausdruck filtert grep die Ausgaben so aus, dass nur diese Zeilen übrigbleiben. Diese sehen dann etwa so aus:
~~~
--2019-11-18 12:57:21-- https://www.example.org/
~~~
und werden "nachbearbeitet"
~~~bash
| sed "s/^.* //"
~~~
Der Streamline-Editor sed löscht aus diesen Zeilen das Datum mit den folgenden Leerzeichen. Es bleibt:
~~~txt
https://www.example.org/
~~~
in diesen sind jedoch etliche Einträge, die ich in der sitemap.txt nicht haben will:
~~~bash
| grep -v "/autoindex-files/"
| grep -v "/font/"
| grep -v "/robots.txt"
| grep -v "/bilder/"
| grep -v "/mime-icons/"
| grep -v "C=S"
| grep -v "C=M"
| grep -v "C=N"
| grep -v "download=1"
| grep -v "buttons.js"
| grep -v "css.css"
| grep -v "favicon.ico"
| grep -v "feed.rss"
| grep -v "opensearch.xml"
~~~
und also jeweils mit grep ausfiltere.
~~~bash
> ${tmpFile};
~~~
Das Ergebnis dieses umfangreichen "Wuselns und Filterns" wird in eine temporäre Datei geschrieben.
~~~bash
tmpFileSorted=$(mktemp);
sort -u < ${tmpFile} > ${tmpFileSorted};
~~~
Es wird eine zweite temporäre Datei angelegt und in diese der sortierte (und `-u` um gleiche Zeilen befreite) Inhalt der ersten temporäre Datei geschrieben.
~~~bash
rm -f ${tmpFile} 2> /dev/null;
~~~
Aufräumen:
~~~bash
mv -f ${tmpFileSorted} /var/www/${servername}/sitemap.txt;
~~~
Hierdurch wird die neue sitemap.txt erstellt. Der Pfad zum Document-Root kann und muss ggf. angepasst werden.
~~~bash
> chmod 644 /var/www/${servername}/sitemap.txt;
~~~
Der Webserver muss diese sitemap.txt lesen können. Er soll diese ja ausliefern, falls eine Suchmaschine danach fragt.
~~~bash
gzip -cf /var/www/${servername}/sitemap.txt > /var/www/${servername}/sitemap.txt.gz;
~~~
Eine Spezialität meines Webservers. Wenn (falls) der Client (Suchmaschinen-Bot) signalsiert, dass gz-komprimierte Daten erlaubt sind, muss der Server diese nicht erst packen sondern liefert die vorgepackte Datei aus. Das spart Serverlast.
~~~bash
chmod 644 /var/www/${servername}/sitemap.txt.gz;
~~~
Auch die komprimierte Datei muss der Webservers also lesen können.
Hints:
* [Die Sitemap kann man dann z.B. bei Google annonsieren](https://search.google.com/search-console/not-verified?original_url=/search-console/sitemaps&original_resource_id).
* Man sollte diese Sitemap aber [mindestens in der robots.txt propagieren](https://wiki.selfhtml.org/wiki/Grundlagen/Robots.txt#Sitemap).
~~~txt
Sitemap: https://www.example.org/sitemap.txt
~~~
Mit ein wenig mehr Gewusel kann mauch einen RSS/Atom-Feed oder eine sitemap.xml erstellen… Allerdings ist (im Gegensatz zum RSS/Atom-Feed deren weiterführender Nutzen, nunja, fragwürdig.