Wir haben noch nicht alle älteren Artikel nachbearbeitet. Das bezieht sich in der Regel nur auf die Codebeispiele, die noch nicht optimal dargestellt werden.
Suche mit alles und scharf, BOSS?
Hinter BOSS steckt ein kostenloser Service von Yahoo. Damit lassen sich Webseiten durchsuchen, die Ergebnisse mit anderen Daten mischen und beliebig darstellen. Chris Heilmann zeigt, wie es geht.
Als ich noch freiberuflich unterwegs war, war eines der meistgefragten Produkte von Kunden, doch bitte eine Suchmaschine für ihre Seite zu erstellen. Besucher sollten die Möglichkeit erhalten, weitere Inhalte zu finden, ohne dass der Seitenbetreiber Verweise auf »weitere Themen« in die Seite einbinden musste.
Damals war das alles nicht so einfach. Entweder schrieb man sein eigenes Skript, das sich durch die Seiten hangelte, nutzte ht://dig oder biss eben in den sauren Apfel und bezahlte Yahoo, Altavista und später Google gutes Geld, um deren Angebote zu nutzen.
Diese Zeiten sind nun vorbei und man kann den gleichen Service kostenlos erhalten. Am Einfachsten ist das mit „Build your Own Search Service“ oder kurz BOSS von Yahoo.
Dieser kostenlose Dienst erlaubt es jedem, das Web oder bestimmte Seiten nach Inhalten zu durchforsten und diese mit anderen Daten zu mischen. Dabei bleibt es einem vorbehalten, wie man die Suchergebnisse darstellen will. BOSS ist derzeit unbegrenzt kostenfrei. In Zukunft wird es eine Beschränkung der Zugriffe pro Tag geben, die entweder durch die Darstellung von Werbung (ein Anteil der Einahmen gehen an den Seitenbetreiber) oder durch Bezahlung erweitert werden kann.
Unabhängig davon ist eines der genialsten Dinge von BOSS die einfache Handhabung. Suchergebnisse sind mittels einer REST-API erreichbar, kommen als JSON, XML oder JSON-P zurück und sind somit sehr einfach innerhalb eines Browsers mittels JavaScript zu verarbeiten.
Am Anfang steht das HTML Formular
Um eine Suchmaske in eine Seite einzubinden, benötigen wir ein einfaches HTML Formular mit den passenden Formularfeldern. Die meisten Suchmaschinen erlauben es, nach bestimmten Seiten zu filtern. Um zum Beispiel Seiten in "wikipedia.de" nach "heilmann" mittels Yahoo zu suchen, reicht es das folgende Formular zu erstellen:
<form id="customsearch"
action="http://de.search.yahoo.com/search">
<div>
<label for="term">Innerhalb der Seite suchen:
<input type="text" name="p" id="term"/>
<input type="hidden" name="vs" id="site"
value="de.wikipedia.org"/>
<input type="submit" value="Ab dafür"/>
</label></div>
</form>
Genauso einfach ist das mit Google:
<form id="customsearch"
action="http://www.google.de/search">
<div>
<abel for="term">Innerhalb der Seite suchen:
<input type="text" name="as_q" id="term"/>
<input type="hidden" name="as_sitesearch" id="site"
value="de.wikipedia.org"/>
<input type="submit" value="Ab dafür"/>
</abel></div>
</form>
Unabhängig davon welche Suchmaschine Ergebnisse anzeigen soll wenn denn kein JavaScript vorhanden ist, verwenden wir die IDs term
für den Suchbegriff und site
für die Seite. Diese werden später im Javascript ausgelesen. Eine ID mit dem Namen customsearch
auf dem Formularelement macht es uns außerdem einfacher, die Javascript-Funktionalität an das richtige Formular zu binden.
Um BOSS zu verwenden, benötigt man einen Developer-API-Key. Bitte holt euch einen Key und ersetzt den im Democode dieses Artikels durch euren.
So funktioniert BOSS
BOSS ist eine REST API, was bedeutet, dass man mit einem einfachen HTTP request oder sogar innerhalb eines Browsers mittels einer URL und verschiedenen Parametern die richtigen Informationen erhalten kann. Um zum Beispiel Wikipedia nach "heilmann" zu durchsuchen, genügt folgender Link (Leerzeichen der Lesbarkeit wegen eingefügt — die Redaktion):
Probiert es einmal selbst aus: klickt den Link und die Suchergebnisse werden in XML angezeigt. Wenn man den format=xml
Parameter weglässt werden die Daten als JSON-Objekt zurückgegeben:
JSON macht am meisten Sinn, wenn man das Objekt direkt an eine JavaScript Funktion übergibt. Um das zu erreichen, genügt es einen callback
-Parameter anzugeben. Wenn wir zum Beispiel SITESEARCH.found()
aufrufen wollen, sobald die Daten zur Verfügung stehen, geht das so:
Man kann diese URL direkt in einem script
-Knoten nutzen. Das folgende Beispiel sucht heilmann
auf de.wikipedia.org
und gibt die Anzahl von Suchergebnissen als Meldung zurück.
<script type="text/javascript">
var SITESEARCH = {};
SITESEARCH.found = function(o){
alert(o.ysearchresponse.totalhits);
}
</script>
<script type="text/javascript"
src="http://boss.yahooapis.com/ysearch/web/v1/heilmann?
sites=de.wikipedia.org&region=de&lang=de&
callback=SITESEARCH.found&appid=Kzv_lcHV34HIybw0GjVkQNnw4AEXeyJ9Rb1gCZSGxSRNrcif_HdMT9qTE1y9LdI-">
</script>
Um allerdings unsere Suchformulare zu erweitern, brauchen wir etwas mehr Funktionalität.
Verbesserung des Suchformulars mit BOSS
Mit diesem Skript erweitern wir unser Suchformular.
SITESEARCH = function(){
var config = {
IDs:{
searchForm:'customsearch',
term:'term',
site:'site'
},
loading:'Lade Ergebnisse...',
noresults:'Keine Ergebnisse gefunden.',
appID:'YOUR-APP-ID',
results:20
};
var form;
var out;
function init(){
if(config.appID === 'YOUR-APP-ID'){
alert('Please get a real application ID!');
} else {
form = document.getElementById(config.IDs.searchForm);
if(form){
form.onsubmit = function(){
var site = document.getElementById(config.IDs.site)
.value;
var term = document.getElementById(config.IDs.term)
.value;
if(typeof site === 'string' &&
typeof term === 'string'){
if(typeof out !== 'undefined'){
out.parentNode.removeChild(out);
}
out = document.createElement('p');
out.appendChild(document
.createTextNode(config.loading));
form.appendChild(out);
var APIurl = 'http://boss.yahooapis.com/ysearch/web/v1/' +
term + '?callback=SITESEARCH.found&sites=' +
site + '&count=' + config.results +
'&appid=' + config.appID;
var s = document.createElement('script');
s.setAttribute('src',APIurl);
s.setAttribute('type','text/javascript');
document.getElementsByTagName('head')[0].appendChild(s);
return false;
}
};
}
}
};
function found(o){
var list = document.createElement('ul');
var results = o.ysearchresponse.resultset_web;
if(results){
var item,link,description;
for(var i=0,j=results.length;i<j ;i++){
item = document.createElement('li');
link = document.createElement('a');
link.setAttribute('href',results[i].clickurl);
link.innerHTML = results[i].title;
item.appendChild(link);
description = document.createElement('p');
description.innerHTML = results[i]['abstract'];
item.appendChild(description);
list.appendChild(item);
}
} else {
list = document.createElement('p');
list.appendChild(document.
createTextNode(config.noresults));
}
form.replaceChild(list,out);
out = list;
};
return{
config:config,
init:init,
found:found
};
}();
Wow, so viel Code! OK, gehen wir Schritt für Schritt durch das Skript.
Wir starten mit einem Modul mit dem Namen SITESEARCH
and geben dem Modul ein Konfigurationsobjekt:
SITESEARCH = function(){
var config = {
IDs:{
searchForm:'customsearch',
term:'term',
site:'site'
},
loading:'Lade Ergebnisse...',
noresults:'Keine Ergebnisse gefunden.',
appID:'YOUR-APP-ID',
results:20
}
Konfigurationsobjekte sind eine sehr gute Idee um es Nutzern zu erlauben, das Skript einfach zu konfigurieren und zu ändern ohne das Skript umzuschreiben. In diesem Beispiel definieren wir die verwendeten IDs, eine Nachricht, die eingeblendet wird während die Dateien laden und eine, die angezeigt wird, falls keine Ergebnisse gefunden werden konnten. Weiterhin definieren wir eine Applikations-ID, die überschrieben werden muss, und erlauben es, die Anzahl der angezeigten Ergebnisse abzuändern.
Warnung: Die hier definierte Applikations ID ist nur ein Platzhalter und "YOUR-APP-ID" muss durch eine echte ID ersetzt werden, ansonsten wird das Skript nicht ausgeführt!
var form;
var out;
function init(){
if(config.appID === 'YOUR-APP-ID'){
alert('Please get a real application ID!');
} else {
Wir definieren form
und out
als Variablen, um sicherzustellen, dass alle Methoden in dem Modul Zugriff auf diese haben. Weiterhin überprüfen wir die Applikations ID und geben eine Fehlermeldung aus, wenn der Platzhalter nicht überschrieben wurde.
form = document.getElementById(config.IDs.searchForm);
if(form){
form.onsubmit = function(){
var site = document.getElementById(config.IDs.site)
.value;
var term = document.getElementById(config.IDs.term)
.value;
if(typeof site === 'string' &&
typeof term === 'string'){
Wenn die Applikations ID definiert ist, überprüfen wir, ob das Formular mit der richtigen ID vorhanden ist und überschreiben das submit
-Event des Formulars. In diesem Event prüfen wir die Werte der anderen Felder. Wenn die Seite, in der wir planen zu suchen, und der Suchbegriff definiert und Zeichenketten sind, kann es weiter gehen.
if(typeof out !== 'undefined'){
out.parentNode.removeChild(out);
}
out = document.createElement('p');
out.appendChild(document
.createTextNode(config.loading));
form.appendChild(out);
Als nächsten Schritt testen wir, ob out
definiert ist. Falls das der Fall ist, löschen wir den Knoten, der in out
gespeichert ist. Der Grund ist, dass die out
-Variable später die Ladenachricht und im letzten Schritt die Suchergebisse beinhalten wird. Daher müssen wir alte Ergebnisse löschen, bevor die neuen angezeigt werden. Wir erstellen einen neuen Paragraphenknoten mit der Ladenachricht und fügen diesen dem Formular hinzu.
var APIurl = 'http://boss.yahooapis.com/ysearch/web/v1/' +
term + '?callback=SITESEARCH.found&sites=' +
site + '&count=' + config.results +
'&appid=' + config.appID;
var s = document.createElement('script');
s.setAttribute('src',APIurl);
s.setAttribute('type','text/javascript');
document.getElementsByTagName('head')[0]
.appendChild(s);
return false;
}
};
}
}
};
Jetzt ist es an der Zeit die BOSS-API aufzurufen, indem wir die passende URL erstellen, und als src
Attribut eines neuen script
Knotens dem Seitenkopf hinzuzufügen. Wir geben dem Event false
als Rückgabewert, um nicht den Browser auf die nächste Seite zu schicken.
Wir definierten SITESEARCH.found
in der API URL als Rückgabemethode, die die Ergebnisdaten weiterverarbeitet. Daher müssen wir diese erstellen.
function found(o){
var list = document.createElement('ul');
var results = o.ysearchresponse.resultset_web;
if(results){
var item,link,description;
Wir erstellen einen neuen Listenknoten und lesen das resultset_web
-Array aus dem Datensatz, der von der API zurückgegeben wurde. Falls keine Suchergebnisse gefunden wurden, ist dieses Array undefiniert, wir müssen also testen, ob es vorhanden ist. Falls das Array definiert ist, erstellen wir drei neue Variablen, die später die Daten eines jeden einzelnen Datensatzes als Werte erhalten werden: Den Titel der Seite, den Verweis und die Beschreibung.
for(var i=0,j=results.length;i<j ;i++){
item = document.createElement('li');
link = document.createElement('a');
link.setAttribute('href',results[i].clickurl);
link.innerHTML = results[i].title;
item.appendChild(link);
description = document.createElement('p');
description.innerHTML = results[i]['abstract'];
item.appendChild(description);
list.appendChild(item);
}
Wir erstellen eine Schleife, in der der Listenknoten um neue Listenelemente mit Verweisen und Paragraphen mit Verweisbeschreibungen erweitert wird.
} else {
list = document.createElement('p');
list.appendChild(document
.createTextNode(config.noresults));
}
form.replaceChild(list,out);
out = list;
};
Falls keine Suchergebnisse gefunden werden konnten, erstellen wir einen neuen Absatz mit einer Fehlermeldung. Wir ersetzen die Ladenachricht entweder mit den Suchergebnissen oder mit diesem Absatz und definieren out
neu.
return{
config:config,
init:init,
found:found
};
}();
Was jetzt noch fehlt, ist zu definieren, welche Methoden und Variablen global erreichbar sein müssen. In diesem Fall brauchen wir found
, da diese von der API aufgerufen wird, init
um das Formular zu verbessern und config
um es Nutzern zu erlauben, die Konfiguration zu überschreiben.
Nutzung des Skripts
Um das Skript zu nutzen, muss es nur nach dem Formular in das Dokument eingebunden, ein API Key definiert sein und die init()
Methode aufgerufen werden.
<form id="customsearch" action="http://search.yahoo.com/search">
<div>
<label for="p">Innerhalb der Seite suchen:</label>
<input type="text" name="p" id="term"/>
<input type="hidden" name="vs" id="site" value="bbc.co.uk"/>
<input type="submit" value="Ab dafür"/>
</div>
</form>
<script type="text/javascript" src="boss-site-search.js">
</script>
<script type="text/javascript">
SITESEARCH.config.appID = 'dein API key';
SITESEARCH.init();
</script>
Wie geht's weiter?
Was wir hier erstellt haben ist nur einfaches Beispiel für das, was man mit BOSS erstellen kann. Man kann in anderen Sprachen und Regionen suchen, Bilder und Nachrichten erhalten und die Ergebnisse mit anderen Informationsquellen mischen. Eine weitere Möglichkeit ist es, mittels dem view=keyterms
-Parameters Schlüsselworte aus den einzelnen Seiten zu extrahieren und es damit ermöglichen, die Suche zu verfeinern. Ein Beispiel dafür in PHP ist im YDN Blog nachzulesen (in Englisch). Für JavaScript ist ausserdem eine Bibliothek mit dem Namem yboss erhältlich die diesen Vorgang erheblich vereinfacht.
Anmerkung der Redaktion
Dieser Artikel ist die deutsche Übersetzung von Christians Beitrag für die Seite 24ways. Dieser Adventskalender bietet noch viele weitere interessante Beiträge, alle in englischer Sprache.
Kommentare
Stefan Walter (Webkraut)
am 04.12.2008 - 12:17
Super-Artikel, vielen Dank dafür an Christian
Herr Voß
am 04.12.2008 - 12:43
Wow. Cooler Tipp! Danke für den Artikel
leo
am 04.12.2008 - 18:18
Sehr fein, dein Javascript ist so selbsterklärend...lovely :)
Vielen Dank!
(Die Links zu dem html-Beispiel und der Javascript-Dateien klappen nicht...)
Jens Grochtdreis
am 05.12.2008 - 14:09
@leo: Danke für den Hinweis. Ich habe es korrigiert.
Claus
am 05.12.2008 - 20:13
Wow, das ist genau das was ich gesucht habe aber selbst nicht wirklich auf die Reihe bringe. Danke!
Natinka
am 06.12.2008 - 11:46
Schöne Sache und danke für den Hinweis. Ich denke dass Yahoo in diesem Bereich ein ganzes Stückchen weiter ist als Google. Ich bin mir auch ziemlich sicher, dass dies der richtige Weg ist - User bestimmte Services anzubieten - um an Google näher ran zu kommen.
Grüße
brigitte
am 10.12.2008 - 17:11
@Christian Heilmann
Hilfreich und gut erklärt!
Schöne Weihnachten und ein gutes Neues Jahr
wünscht
Brigitte Weber-Frowein
Ell
am 12.12.2008 - 10:03
Tja, liest sich ganz gut. Ist aber alles JavaScript - was ist denn, wenn der Besucher JavaScript deaktiviert hat?
Dann muß man die Suchanfrage doch auf seinem Server verarbeiten?
Eric Eggert (Webkraut)
am 12.12.2008 - 10:26
@Ell: Dann wird das Formular ganz normal abgeschickt und der Besucher landet bei einer Yahoo!- oder Google-Suche.
Die Kommentare sind geschlossen.