deutsch     english     français     Drucken

 

6.3 BINGSEARCH, DICTIONARY

 

 

EINFÜHRUNG

 

Es ist möglich, bekannte Suchmaschinen wie Google, Bing oder Yahoo zu verwenden, um programmgesteuert eine Websuche durchzuführen. Dazu musst du eine bestimmte URL des Anbieters mit zusätzlichen Parametern ergänzen, die den Suchstring enthalten, und damit einen HTTP-GET-Request durchführen. Diese Angaben werden von einer Webapplikation, d.h. einem Programm, dass auf dem Webserver läuft, ausgewertet und als HTTP-Response an dich zurückgegeben [mehr... Das Serverprogramm kann in verschiedenen Programmiersprachen geschrieben sein,
weit verbreitet sind PHP, Java, Ruby und Python. Webapplikationen
können mit dem Django-Framework auch in Python geschrieben werden
].

Gewisse Web-Suchmaschinen-Betreiber stellen überdies Web-Dienste zur Verfügung, die sich über ein Programmier-Interface (API, Applicaton Programminng Interface) verwenden lassen. Diese Dienste sind zwar meist kostenpflichtig, für Schulungs- und Entwicklungszwecke gibt es aber oft einen etwas eingeschränkten kostenfreien Zugang. Beispielsweise kannst du mit dem Bing Search API deine eigene in Python geschriebene Web-Suchmaschine erstellen, die Suchresultate mit einem von dir erfundenen Layout zeigt.

Search APIs  liefern das Resultat meist in einer speziellen Formatierung, nämlich der JavaScript Object Notation (JSON), zurück. Mit der Bibliotheksklasse json kann daraus ein Dictionary erstellt werden. Um daraus bestimmte Informationen zu extrahieren, musst du daher zuerst verstehen, was man in Python unter einem Dictionary versteht.

PROGRAMMIERKONZEPTE: Web-Search, Python-Dictionary

 

 

EIN DICTIONARY VERSTEHEN

 

Wie der Name vermuten lässt, handelt es sich bei einem Dictionary um eine Datenstruktur ähnlich einem Wörterbuch. Dabei steht links das Wort in der dir bekannten Sprache und daneben das Wort in der Fremdsprache (wir sehen von Vieldeutigkeit ab), beispielsweise für einige Farbnamen von deutsch nach englisch:

  Deutsch   Englisch
  blau   blue
  rot   red
  grün   green
  gelb   yellow

(In einem Wörterbuch sind die Wörter alphabetisch geordnet, damit das Auffinden vereinfacht wird.)

Man nennt das linke Wort den Schlüssel (key) und das rechte Wort den Wert (value). Ein Dictionary besteht also aus Schlüssel-Wert-Paaren (key-value-pairs) [mehr... Ein key-value-strukturierter Datentyp wird auch assoziatives Feld, Map, Hash, Hashtable, Hashmap, u.a. genannt]. Sowohl Schlüssel wie Werte können beliebige Datentypen haben [mehr... Schlüssel müssen allerdings einen unveränderlichen Datentyp haben. Dies schliesst aus, als Schlssel Listen zu verwenden, erlaubt aber Zahlen, Strings und Tuples. ].

Dein Programm übersetzt die oben angegebenen Farben von deutsch auf englisch. Wenn die Eingabe nicht im Wörterbuch ist, wird der Fehler abgefangen und eine Fehlermeldung ausgeschrieben.

lexicon = {"blau":"blue", "rot":"red", "grün":"green", "gelb":"yellow"}

print "All entries:"
for key in lexicon:
    print key + " -> " + lexicon[key]

while True:
    farbe = input("color (deutsch)?")
    if farbe in lexicon:
        print farbe + " -> " + lexicon[farbe]
    else:
        print farbe + " -> " + "(not translatable)" 
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

 

MEMO

 

Ein Dictionary besteht aus Schlüssel-Werte-Paaren (key-value-pairs). Im Unterschied zu Listen sind diese Paare allerdings nicht geordnet. Bei der Definition verwendet man ein geschweiftes Klammerpaar und trennt die Paare mit einem Komma, sowie Schlüssel und Wert mit einem Doppelpunkt (Leerschläge spielen für die Formatierung keine Rolle).

Wichtige Operationen:


dictionary[key]  Liefert den Wert zum Schlüssel key (falls key existiert)
dictionary[key] = value  Fügt ein neues Schlüssel-Wert-Paar hinzu oder modifiziert Wert
len( dictionary)  Liefert die Anzahl Schlüssel-Wert-Paare
del  dictionary(key)  Löscht das Paar (Schlüssel und Wert) mit dem Schlüssel key
key in  dictionary  Liefert True, falls der Schlüssel key vorhanden ist
dictionary.clear()  Löscht alle Einträge, es bleibt eine leeres Dictionary

Ein Dictionary kann man mit einer for-Schleife

for key in dictionary: 
durchlaufen (iterieren).

 

 

DICTIONARIES SIND EFFIZIENTE DATENSTRUKTUREN

 

Du hast richtig gedacht, wenn du einwendest, dass man gepaarte Informationen auch in einer Liste abspeichern könnte. Naheliegend wäre es, die Paare als Teillisten in einer umfassenden Liste zu speichern. Wozu gibt es Dictionary als eigene Datenstruktur?

Der grosse Vorteil von Dictionaries besteht darin, dass du bei Vorgabe des Schlüssels mit der Klammernotation einfach und schnell auf seinen Wert zugreifen oder anders gesagt, dass du Dictionaries effizient durchsuchen kannst. Das effiziente Auffinden von Information spielt natürlich nur bei grossen Datenmengen eine Rolle, wenn es sich also um hunderte, ja tausende von Schlüssel-Werte-Paaren handelt.

Als interessante und nützliche Anwendung soll dein Programm die Postleitzahl irgend einer Stadt in der Schweiz finden. Dazu verwendest du eine Textdatei chplz.txt, die du von hier herunterladen kannst. Du kopierst sie in das Verzeichnis, in dem sich dein Programm befindet. Die Datei ist zeilenweise wie folgt strukturiert (und besitzt keine Leerzeile, auch nicht am Ende):

Aarau:5000
Aarburg:4663
Aarwangen:4912
Aathal Seegraeben:8607
...

Deine erste Aufgabe besteht darin, diese Textdatei in ein Dictionary zu verwandeln. Dazu liest du sie zuerst mit read() als String ein und spaltest sie mit split("\n") in einzelne Zeilen auf [mehr... In der Datei können können die Zeilen nach Windows-Standard mit <CR><LF>
oder nach Unix-Standard mit <LF> getrennt sein. Als String eingelesen ist der Zeilentrenner in beiden Fällten <LF> = \n
].

Für die Erstellung des Dictionary trennst du die Zeilen nochmals mit dem Doppeltpunkt als Trennzeichen in Schlüssel und Wert und fügst das neue Paar mit der Klammernotation in das (zuerst leere) Dictionary ein. Wie vorhin mit den Farben kannst du nun mit der Klammernotation auf eine Postleitzahl zugreifen.

file = open("chplz.txt")
plzStr = file.read()
file.close()

pairs = plzStr.split("\n")
print str(len(pairs)) + " pairs loaded"
plz = {}

for pair in pairs:
    element = pair.split(":")
    plz[element[0]] = element[1]

while True:
    town = input("City?")
    if town in plz:
        print "The postal code of " + town + " is " + str(plz[town])
    else:
        print "The city " + town + "was not found."
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)

 

 

MEMO

 

Mit einem Dictionary kann man sehr einfach und schnell auf einen Schlüsselwert zugreifen [mehr... Es wird der Hash-Algorithmus verwendet].

 

 

BING FÜR EIGENE ZWECKE BRAUCHEN

 

Dein Programm verwendet die Suchmaschine Bing, um mit einem vom Benützer eingegebenen Suchstring nach Websites zu suchen und die vom Server gelieferten Informationen auszuschreiben.

Damit du den Such-Dienst verwenden kannst, benötigst du einen Authentifizierungs-Schlüssel. Um diesen zu erzeugen, besuchst du die Website https://www.microsoft.com/cognitive-services/en-us/apis und wählst "Get started for free." Nachfolgend wirst du aufgefordert, deinen bestehenden Microsoft- Account zu verwenden oder einen neuen zu erstellen.

Auf der angezeigten Seite von Microsoft Cognitive Services wählst du "APIs" und "Bing Web Search" und klickst auf "Request new trials".

Scrolle nach unten und wähle "Bing Search-Free".

 

Nach der Bestätigung mit "Subscribe" kriegst du zwei Schlüsselwerte, von denen du nur einen im Python-Programm verwenden musst.

Speichere die Schlüsselwerte mit Kopieren&Einfügen für eine weitere Verwendung in einer Textdatei. Du kannst diese Schlüssel auch jederzeit unter deinem Microsoft-Account wieder abrufen.

 

In deinem Programm sendest du einen GET-Request, der mit einem Suchstring ergänzt ist. Der Response von Bing ist ein String, in dem die Informationen mit geschweiften Klammern strukturiert sind.  Die Formatierung entspricht der JavaScript Object Notation (JSON). Mit der Methode json.load() kann der String in ein ineinander geschachteltes Python-Dictionary umgewandelt werden, das sich leichter durchsuchen lässt. Du kannst die Verschachtelung analysieren, indem du in einer Testphase geeignete Informationen in der Konsole ausschreibst. Später kannst du diese Zeilen wieder auskommentieren oder entfernen. Was findet Bing mit dem Suchstring "Hillary Clinton"?

import urllib2
import json

def bing_search(query):
    key = 'xxxxxxxxxxxxxxxxxxxxx' # use your personal key
    url = 'https://api.cognitive.microsoft.com/bing/v5.0/search?q=' + query
    urlrequest = urllib2.Request(url)
    urlrequest.add_header('Ocp-Apim-Subscription-Key', key)
    responseStr = urllib2.urlopen(urlrequest)
    response = json.load(responseStr)
    return response

query = input("Enter a search string(AND-connect with +):")
results = bing_search(query)
#print "results:\n" + str(results)
webPages = results['webPages']
print "Number of hits:", webPages["totalEstimatedMatches"]
print "Found URLs:"
values = webPages.get('value')
for item in values:
    print item["displayUrl"]
Programmcode markieren (Ctrl+C kopieren, Ctrl+V einfügen)


 

MEMO

 

Wie du im String result siehst, kann ein Dictionary als Werte wiederum Dictionaries enthalten. Damit lassen sich hierarchische Informationsstrukturen, ähnlich wie XML, erstellen.

Die Authentifizierung erfolgt über einen zusätzlichen Header-Eintrag im GET-Request. Du kannst die Bing-Suche durch Query-Parameter beeinflussen. Beispielsweise fügst du in der URL "&count=20" an, damit du 20 Antwort-Werte erhältst. Nähere Angaben findest du hier.

 

 

AUFGABEN

 

1.


Verbessere das Postleitzahl-Programm schrittweise so, dass eine Stadt auch dann gefunden wird, wenn man 
a. Leerschläge vor oder nach dem Städtenamen eingibt
b. sich nicht konsequent an die Gross-Kleinschreibung hält
c. Umlaute als Ae, Oe, Ue, ae, oe, ue schreibt
d. Accents weglässt (Achtung: Es gibt einen Konflikt bei ö)
e. Einige Orte sind mehrdeutig, haben aber eine Zusatzangabe. Wie willst du damit umgeben?

2.

Verwende den Bing-Search, um vom Suchresultat mit dem höchsten Ranking den Titel und den Inhalt in einer HtmlPane auszuschreiben. Beispielsweise sollte  mit dem Suchstring "tigerjython" ungefähr Folgendes erscheinen: