Jour 2 – Indexation des vidéos du Collège de France

Enseigner librement la recherche en train de se faire à tous les publics intéressés, faciliter la diffusion des connaissances, favoriser l’émergence de disciplines nouvelles et l’approche multidisciplinaire de la recherche de haut niveau, contribuer à l’image internationale de notre pays dans les domaines de la recherche et de la culture : telles sont, depuis des siècles, les missions du Collège de France. (Paragraphe honteusement copié du programme 2014-2015.)

Presque tous les cours sont filmés, et il serait intéressant d’indexer tout le contenu de manière à pouvoir profiter de ce gisement de 4 091 vidéos de manière organisée. En particulier, ce serait bien de pouvoir rechercher des vidéos avec autocomplétion, comme ceci (essayez « lions », « psychologie ») :

Pour cela, il faut :

Récupération des données des vidéos

Sur la page de recherche du Collège de France, le code HTML des vidéos est organisé comme suit :

<li class="video">
    <a href="http://www.college-de-france.fr/site/tony-cragg/Conference.htm" data-target="leaf">
        <span class="date">03 décembre 2014</span>
        <span class="lecturer">Tony Cragg</span>
        <span class="title">Présentation de son œuvre</span>
    </a>
</li>
<li class="audio-video">
    <a href="http://www.college-de-france.fr/site/anatole-abragam/symposium-2014-11-28-17h35.htm" data-target="leaf">
        <span class="date">28 novembre 2014</span>
        <span class="lecturer">Nina Abragam</span>
        <span class="title">Quelques mots de conclusion</span>
    </a>
</li>

Et on aimerait l’obtenir dans un format réutilisable par l’outil d’autocomplétion de Twitter (JSON, par exemple) :

{
    "url": "http://www.college-de-france.fr/site/tony-cragg/Conference.htm",
    "date": "03 d\u00e9cembre 2014",
    "lecturer": "Tony Cragg",
    "title": "Pr\u00e9sentation de son \u0153uvre"
},
{
    "url": "http://www.college-de-france.fr/site/anatole-abragam/symposium-2014-11-28-17h35.htm",
    "date": "28 novembre 2014",
    "lecturer": "Nina Abragam",
    "title": "Quelques mots de conclusion"
}

On peut accomplir cette tâche via un procédé qui s’appelle scraping (pas toujours légal). Il existe un package Python, BeautifulSoup, qui permet d’accomplir cela facilement :

from bs4 import BeautifulSoup
import json

html = open('page1.html').read()

b = BeautifulSoup(html)
menu = b.find('ul', 'menu')
videos = []
for line in menu.findAll('li'):
    url = line.find('a')['href']
    date = line.find('span', 'date').text
    lecturer = line.find('span', 'lecturer').text
    title = line.find('span', 'title').text
    videos.append({'url': url, 'date': date, 'lecturer': lecturer, 'title': title, 'tokens': title.split() + lecturer.split()})

with open('cdf.json', 'w') as f:
    f.write(json.dumps(videos))

Les informations sur les vidéos sont donc enregistrées dans le fichier cdf.json.

Application du framework d’autocomplétion

On a un peu de JavaScript à faire. Je ne comprends pas ce que tout ce code fait, mais j’ai pris l’exemple de Twitter en modifiant les choses importantes (principe fondamental de la bidouille, concept indissociable de la programmation) :

var videos = new Bloodhound({
    datumTokenizer: function(d) { return d.tokens; },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    prefetch: '_static/cdf.json'
});
videos.initialize();

Ici, le lien vers le fichier cdf.json. Ci-dessous, on indique quels champs on souhaite voir apparaître dans les suggestions (en l’occurrence, la date date, le titre value, et les intervenants lecturer) :

$('.typeahead').typeahead(null, {
    name: 'videos',
    source: videos.ttAdapter(),
    templates: {
        suggestion: Handlebars.compile([
            '<p class="repo-language">{{date}}</p>',
            '<p class="repo-name">{{value}}</p>',
            '<p class="repo-description">{{lecturer}}</p>'
        ].join(''))
    }
});

Enfin, en cas de sélection, on modifie la page pour permettre à l’utilisateur de consulter la vidéo :

$('input.typeahead').on('typeahead:selected', function(event, selection) {
  $('#result').attr('href', selection.url);
  $('#result').html('Accéder à la vidéo <em>' + selection.value + '</em> par ' + selection.lecturer);
}).on('typeahead:autocompleted', function(event, selection) {
  $('#result').attr('href', selection.url);
  $('#result').html('Accéder à la vidéo <em>' + selection.value + '</em> par ' + selection.lecturer);
});

Aujourd’hui, c’était programmation-bidouille, demain ce sera algorithmique, promis.

Ressources utiles