6.3 RECHERCHE BING, DICTIONNAIRES

 

 

INTRODUCTION

 

Il est possible d’utiliser des moteurs de recherche connus tels que Google, Bing ou Yahoo pour effectuer des recherches programmatiques sur le Web. Au lieu de taper des mots-clés dans un formulaire sur le site Web du moteur de recherche, il s’agit d’effectuer par programme une requête HTTP GET sur une URL du site en fournissant des paramètres supplémentaires. Ces données sont ensuite évaluées par une application Web, c’est-à-dire un programme exécuté par le serveur Web chargé de les traiter et de retourner les résultats sous forme de réponse HTTP [plus...le côté serveur de l’application Web peut être développé dans de nombreux langages de programmation dont les plus répandus sont le PHP, Java, Ruby et Python. On peut toutefois également développer des applications Web à l’aide de Python grâce aux frameworks Django, Flask ou aux dizaines d’autres existant].

De plus, certains moteurs de recherche mettent à disposition un service de recherche utilisable par l’intermédiaires d’une API (Application Programming Interface). Bien que ces services soient généralement payants, ils sont parfois disponibles gratuitement en version restreinte pour faciliter le développement d’applications ainsi que la prise en main de l’API. L’API du moteur de recherche Bing est par exemple disponible en version limitée et permet ainsi de créer soi-même une interface graphique personnalisée pour lancer des recherches Bing.

Les API des moteurs de recherche retournent les données dans un format spécial appelé JSON (JavaScript Object Notation). Le module Python json permet de convertir facilement du JSON en un dictionnaire Python. De ce fait, pour être en mesure d’extraire les informations retournées en JSON par le moteur de recherche Bing, il faudra d’abord savoir précisément ce que sont les dictionnaires Python et comment on les manipule.

CONCEPTS DE PROGRAMMATION: Application Web, Dictionnaires Python

 

 

COMPRENDRE LES DICTIONNAIRES

 

Comme son nom l’indique, un dictionnaire est une structure de données similaire à un dictionnaire de langue. On peut imaginer des paires de mots formées d’un mot connu à gauche et d’un mot de la langue étrangère à droite en excluant toute ambiguïté : on imagine que tout mot de la langue d’origine comporte une unique signification dans la langue étrangère (ce qui est faux en réalité). L’exemple ci-dessous montre la correspondance entre les noms de couleurs en français et en anglais :

  Français   Englisch
  bleu   blue
  rouge   red
  vert   green
   jaune   yellow

(Dans un vrai dictionnaire, les mots sont cependant arrangés dans l’ordre alphabétique afin de simplifier la recherche d’un mot spécifique.)

Le mot de la colonne de gauche est la clé (key) et le mot de droite est la valeur (value). Un dictionnaire contient donc des paires clé-valeur. Les valeurs peuvent prendre n’importe quel type de données et les clés n’importe quel type de données immutable. Ceci exclut la possibilité d’utiliser des listes ou dictionnaires en tant que clé d’un dictionnaire mais autorise en revanche les nombres, les chaines de caractères et les tuples.

Le programme ci-dessous traduit du français vers l’anglais les couleurs mentionnées dans le tableau précédent. Si le mot saisi n’est pas une clé du dictionnaire (colonne de gauche), l’erreur est gérée et un message est affiché dans la console.

lexicon = {"bleu":"blue", "rouge":"red", "vert":"green", "jaune":"yellow"}

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

while True:
    color = input("couleur (français)?")
    if color in lexicon:
        print color + " -> " + lexicon[color]
    else:
        print color + " -> " + "(not translatable)" 
Sélectionner le code (Ctrl+C pour copier, Ctrl+V pour coller)

 

 

MEMENTO

 

Un dictionnaire est un ensemble de paires clé-valeur. À la différence des listes, ces paires ne sont pas ordonnées. Pour définir un dictionnaire, on utilise des accolades {}, on sépare les paires par des virgules et les clés des valeurs par un double-point de la manière suivante :
>>> dictionnaire = {clé1 : valeur1, clé2 : valeur2, …}

Important operations:


dictionary[key] Retourne la valeur associée à la clé key si la clé existe
dictionary[key] = value Ajoute une nouvelle paire clé-valeur ou change la valeur associée à la clé key
len( dictionary) Retourne le nombre de paires clé-valeur présentes dans le dictionnaire
del dictionary(key) Supprime la paire dont la clé est key
key in  dictionary Retourne True si la clé key existe
dictionary.clear() Supprime toutes les paires. Il reste donc un dictionnaire vide

On peut parcourir un dictionnaire à l’aide d’une boucle for de la manière suivante

for key in dictionary: 

 

 

LE DICTIONNAIRE, UNE STUCTURE DE DONNÉES PERFORMANTE

 

Vous vous demandez peut-être pourquoi il faut une nouvelle structure de données pour stocker des paires clé-valeur alors qu’on pourrait très bien les stocker dans une liste dont les éléments seraient de courtes listes de deux éléments [clé, valeur].
Le gros avantage des dictionnaires réside dans la facilité d’accès aux paires sur la base de la clé à l’aide des crochets carrés. En d’autres termes, il est très facile de vérifier si une information s’y trouve ou non et de la retourner le cas échéant. Il ne s’agit pas simplement d’une facilité de langage mais d’un réel gain de performance par rapport à une liste. L’avantage des dictionnaires sur les listes pour trouver une information devient très évident lorsqu’il y a des centaines, voire des milliers ou des millions de paires clé-valeur.

Comme application intéressante, le programme ci-dessous retourne le numéro postal de n’importe quelle ville suisse. Les données se trouvent dans le fichier texte chplz.txt disponible en téléchargement grâce au lien précédent. Copiez ce fichier dans le même dossier que votre programme Python. Le fichier contient sur chaque ligne du fichier une association ville-NPA et ne comporte aucune ligne vide, même tout à la fin :

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

La première étape consiste à charger ce fichier dans la mémoire en créant un dictionnaire contenant les paires ville(clé)-NPA(valeur). On utilise à ce dessein la fonction read() pour le charger en tant que chaine de caractères dans la variable plzStr qui sera ensuite séparée ligne par ligne grâce à la méthode split("\n") [plus...Dans le fichier lui-même, les fins de lignes peuvent être marquées selon le standard Windows avec les caractères <CR><LF> ou selon le standard Unix avec <LF> uniquement. Une fois le contenu du fichier chargé en mémoire dans une chaine de caractères, les fins de lignes sont heureusement marquées par la séquence d’échappement \n dans les deux cas..].

Pour construire le dictionnaire, il faut séparer la clé (ville) et la valeur (npa) de chaque ligne sur la base du double-point et les ajouter à l’aide des crochets carrés au dictionnaire plz qui est initialement vide. Une fois le dictionnaire construit, il est possible d’accéder facilement à un numéro postal en indiquant la ville désirée entre crochets carrés.

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.")
Sélectionner le code (Ctrl+C pour copier, Ctrl+V pour coller)

 

 

MEMENTO

 

Il est vraiment très facile et très rapide d’accéder à la valeur correspondant à une certaine clé dans un dictionnaire [plus... On utilise pour ce faire un algorithme de hachage].

 

 

UTILISER BING POUR SON PROPRE PROFIT

 

Le programme ci-dessous utilise le moteur de recherche Bing pour rechercher des sites correspondant à la requête saisie par l’utilisateur et afficher les résultats retournés. Pour pouvoir accéder au service de recherche Bing, il faut disposer d’une clé d’authentification personnelle qu’il faut se procurer de la manière suivante:

Visiter la page https://www.microsoft.com/cognitive-services/en-us/apis et choisir "Get started for free". Vous allez devoir fournir le mot de passe de votre compte Microsoft ou en créer un nouveau. Dans la page intitulée Microsoft Cognitive Services, sélectionner "APIs" et "Bing Web Search" puis cliquer sur "Request new trials".  Descendre dans la page et choisir "Search Bing-Free". Après avoir confirmé en cliquant sur "Subscribe", vous recevrez deux valeurs. Sauvegardez l’une d’elles par copier-coller dans un fichier texte car vous en aurez bientôt besoin. Il est également possible de retrouver ces clés sous votre compte Microsoft.

Le programme ci-dessous procède en envoyant une requête HTTP GET dans laquelle figure la requête de la recherche. La réponse de Bing est une chaine de caractères dans laquelle l’information est structurée par des accolades, selon le format JSON. La méthode json.load() permet de convertir cette chaine de caractères en un dictionnaire Python qui peut être analysé plus efficacement. Durant la phase de test, il peut être utile de bien étudier les différentes imbrications des données en imprimant la réponse JSON vers la console. Ces lignes peuvent être supprimées ou commentées par la suite. Quelles pages Bing trouve-t-il pour la requête "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"])
Sélectionner le code (Ctrl+C pour copier, Ctrl+V pour coller)

 

 

MEMENTO

 

Comme le montre cet exemple, un dictionnaire peut contenir d’autres dictionnaires comme valeurs, ce qui permet de créer des structures d’information hiérarchiques de manière similaire au XML.

La clé d’authentification est utilisée dans un en-tête HTTP supplémentaire de la requête GET. Il est possible de personnaliser la recherche Bing en spécifiant des paramètres additionnels. Par exemple, en ajoutant la chaine "&count=20" à l’URL, le nombre de résultats est limité à 20. Pour plus d’informations, consulter la référence de l’API.

 

 

EXERCICES

 

1.


Améliorer de manière incrémentale le programme permettant de retrouver le code postal d’une ville suisse même dans les cas suivants :

a. Dans le champ de saisie, le nom de la ville peut être précédé et suivi de caractères d’espacement.
b. Le nom de la ville est saisi en mélangeant majuscules et minuscules
c. Les trémas des noms de villes germanophones sont remplacés par les séquences Ae, Oe, ae, oe, et ue
d. Les accents sont omis des noms des villes (ceci engendre une ambigüité pour ö)
e. Certaines localités portent des noms ambigus mais disposent d’informations supplémentaires. Proposer un moyen de s’en sortir avec ces cas spéciaux.
2.

Effectuer une recherche Bing pour écrire le titre et le contenu du résultat disposant du score de pertinence le plus élevé dans un HtmlPane. Par exemple, pour la requête de recherche « tigerjython », le résultat devrait ressembler à la capture ci-dessous :