Meta-Press.es

Moteur de recherche décentralisé & revue de presse automatisée

Documentation

1. Comment installer l’extension ?

Pour installer Meta-Press.es sur votre navigateur (Firefox ou dérivés, comme le Tor Browser) : ouvrir la page suivante addons.mozilla.org et cliquer sur le gros bouton bleu + Ajouter à Firefox.

Une discussion est en cours concernant les permissions demandées par Meta-Press.es. C’est pour l’instant une permission générique et un peu trop large, mais qui fonctionne. Il est recommendé d’autoriser Meta-Press.es à fonctionner en mode "privé" aussi. Ces fonctionnalités sont nouvelles dans Firefox et changeantes.

2. Comment s’en servir ?

Une fois installée, l’extension crée un bouton dans la barre d’outils, avec l’icône de l’étoile filante de Meta-Press.es.

icone metapresses
Figure 1. bouton portant l’icône de Meta-Press.es

Un clic sur ce bouton ouvre un nouvel onglet sur l’interface du moteur de recherche.

20191029 meta press filters
Figure 2. interface du moteur de recherche

Sous le nom de l’extension dans cet onglet, les gros titres des journaux sélections sont chargés et défilent.

Vous pouvez saisir votre requête et choisir dans quels journaux chercher, grâce au mécanisme multi-critères de filtrage des sources.

Les résultats sont ensuite listés en dessous quand ils arrivent.

Chaque résultats comporte un titre, un lien vers l’article, sa source, sa date, et potentiellement un auteur et un extrait :

20191029 meta press result
Figure 3. détails d’un résultat

Les outils pour travailler sur ces résultats (tri, filtrage, sélection), apparaissent dans la colonne à droite des résultats.

20171216 meta press country
Figure 4. nombre de résultats par source et filtrage par source, en cliquant sur le nom d’une source
20171216 meta press country
Figure 5. filtrage par date

Vous pouvez par exemple cliquer sur le lien "Toggle selection mode" pour faire apparaître une case à cocher pour chaque résultat et commencer à en sélectionner. Vous pouvez ensuite exporter cette sélection en différents formats (JSON, RSS, ATOM, et bientôt CSV).

20191029 meta press europe selection mode crop circles
Figure 6. mode de sélection pour export

Pour ré-importer les résultats d’une recherche exportés dans un fichier, cliquez sur le lien "Import JSON" (ou resp. RSS, ATOM) dans la barre horizontale turquoise tout en haut, et sélectionnez le fichier en question dans le sélecteur de fichier qui s’ouvre alors.

3. Comment ajouter une source au moteur de recherche ?

Si vous êtes un programmeur, ajoutez simplement une entrée dans le fichier js/sources.json.

Pour tester votre travail avant de l’envoyer, vous pouvez importer vos propres sources depuis les paramètres de l’extension.

Voici quelques exemples utiles, listés en haut du fichier js/sources.json :

  • Mediapart.fr/en est un bon exemple, de source "normale" utilisant des sélecteurs CSS

  • New Europe est un exemple de source fournissant ses résultats au format RSS

  • New Europe Greece étend la définition de source New Europe

  • The Washingtown Post fourni ses résultats en JSON

  • The Japan News utilise la méthode HTTP POST

  • Helsinky Times a besoin de sélecteurs XPaths pour récupérer certains champs

3.1. Méthodologie

  • Tout d’abord, charger la page de la source à ajouter et noter l’adresse où récupérer une actualité (les gros titres).

  • Puis, tester la fonctionnalité de recherche :

    • Vérifier si les résultats sont accessibles en RSS (ou ATOM) en utilisant les outils de Développeurs de Firefox (touche F12, onglet par défaut Inspecteur, rechercher "rss") cela économiserait 2/3 du travail d’intégration

      • si c’est le cas, penser à ajouter une entrée "favicon_url" dans l’objet JSON de description de la source, pour attribuer la bonne icône aux résultats

      • toujours si c’est le cas : il n’est pas nécessaire de préciser le fuseau horaire ("tz") de la source dans les tags

    • sinon, noter l’URL des résultats

    • vérifier que cette URL fourni des résultats triés du plus récent au plus ancien, ou chercher à obtenir ce tri, sinon la source est dite incompatible, voir l’encart ci-dessous

    • si l’URL des résultats ne comporte pas vos termes de cherche, c’est que cette source utilise la méthode HTTP POST, vous pouvez alors vous inspirer de la source The Japan News

    • essayer de faire une recherche sur plusieurs termes et d’obtenir des résultats contenant l’ensemble de vos termes (termes liés par un "et" logique) il est par exemple généralement possible d’ajouter des guillemets autour du groupe de termes. S’il n’est pas possible d’obtenir un "et" logique entre les termes, alors il faudra préciser le tag "or logic" dans les tags techniques.

    • Enfin, noter une recherche donnant des résultats. Les termes de recherche par défaut sont "quadrature du net" mais "gilets jaunes" ou "yellow vests" complètent bien quand il y a besoin.

Si quelques chose se passe mal, comme par exemple :

  • pas de fonctionnalité de recherche

  • pas de date sur les résultats

  • pas de tri par date

Il est important de contacter la source en question pour lui proposer de faire évoluer sa fonctionnalité de recherche, puis de lister la source parmi les sources incompatibles où l’on peut également noter l’état d’avancement de sa tentative de retour utilisateur auprès de la source.

Il est également possible de contacter les sources n’ayant pas encore été contactées, et n’ayant donc pas encore d’information concernant le statu du retour utilisateur à leur formuler.

Une fois ces premiers tests effectués, vous pouvez vous lancer sereinement dans la rédaction de votre définition de source. Il y a 4 sortes d’informations à fournir :

  • informations générales : le nom, le fuseau horaire, la langue et autres à la fin ;

  • gros titre : deux entrées pour récolter un gros titre sur la page d’accueil de cette source ;

  • recherche : l’URL du moteur de recherche de la source ;

  • analyse des résultats : 5 entrées pour décrire les champs des résultats (les deux dernières étant facultatives) :

    • titre : r_h1

    • lien : r_url

    • date : r_dt

    • extrait : r_txt

    • auteur : r_by

Chacune que ces entrées peut être suivie d’une entrée du même nom mais suffixée _attr ou _re, afin de préciser un attribut de balise HTML à lire, ou effectuer un remplacement du texte pointé par motif d’expression rationelle (via la fonction .replace() du JavaScript). La version _re doit donc définir une liste de deux éléments : le premier est la chaîne de caractère permettant de créer l’expression rationelle (RegEx) en question, et le second est le motif de remplacement (il y a des exemples un peu plus bas).

Il est encore possible de donner une entrée suffixée par _xpath pour utiliser un sélecteur XPath au lieu d’un sélecteur CSS.

3.2. Documentations sur CSS, RegEx et XPath

3.2.1. JSON

La syntaxe JSON chez Mozilla ou json.org : gardez juste en tête qu’il faut utiliser des guillemets doubles et ne pas laisser de virgules trainantes.

3.2.2. Sélecteurs CSS

Documentation Mozilla concernant les sélecteur CSS

Une seconde doc. sur le sujet CSS selectors complète et bien illustrée, mais en anglais sur medium.com

3.2.3. RegEx : expressions rationelles

Expressions Régulières, par Mozilla.

Vue d’ensemble en anglais.

3.2.4. XPath

Documentations Mozilla en français.

XPath vision d’ensemble, en anglais

3.3. Exemples

3.3.1. Définition de source basée RSS

{
	"https://www.neweurope.eu": {
		"favicon_url": "https://www.neweurope.eu/wp-content/uploads/2019/07/NE-16.jpg",
		"headline_url": "https://www.neweurope.eu",
		"headline_selector": ".td-module-meta-info .entry-title a",
		"search_url": "https://www.neweurope.eu/search/{}/feed/rss2/", (1)
		"extends": "RSS", (2)
		"tags": {  } (3)
	}
}
1 Dans cette URL, Meta-Press.es remplacera le jeton {} par vos termes de recherche.
2 Cette définition s’appuie sur la définition générique fournie pour les flux RSS et l’étend à notre cas particulier.
3 Les tags sont expliqués plus bas

3.3.2. Extension de vos propres définitions de source

	"https://www.neweurope.gr": {
		"favicon_url": "https://www.neweurope.gr/wp-content/uploads/2019/07/favicongr-16.jpg",
		"headline_url": "https://www.neweurope.gr",
		"search_url": "https://www.neweurope.gr/search/{}/feed/rss2/",
		"extends": "https://www.neweurope.eu", (1)
		"tags": {  }
	}
1 Ici "https://www.neweurope.eu" est la clé de la source à étendre, la première chaîne de caractère d’une source.

3.3.3. Définition de source basées sur JSON

Pour diagnostiquer un cas de chargement des résultats via une requête AJAX et travailler sur l’objet JSON correspondant il est possible de s’appuyer sur les outils développeurs de Firefox. La touche F12 permet d’ouvrir la fenêtre correspondante, puis se rendre dans la console JavaScript. Les requêtes XHR qui ont lieu après le chargement initial de la page inspectée y apparaissent. Une fois la requête repérée, l’outil permet de déplier les informations associées, dont le contenu de la réponse reçue (ici c’est donc un objet JSON) de parcourir ce contenu voire effectuer des recherches dedans.

Si la requête inspectée contient bien les résultats de notre recherche on dispose de son adresse et il reste à préciser les chemins d’accès à chaque information.

	"https://www.washingtonpost.com": {
		"type": "JSON",
		"search_url": "https://sitesearchapp.washingtonpost.com/sitesearch-api/v2/search.json?query={}&count={#}&sort=displaydatetime desc",  (1) (2)
		"favicon_url": "https://www.washingtonpost.com/favicon.ico",
		"res_nb": "results.total", (3)
		"results": "results.documents", (4)
		"r_h1": "headline",
		"r_url": "contenturl",
		"r_dt": "pubdatetime",
		"r_txt": "blurb",
		"r_by": "authors", (5)
		"r_by_attr": "name", (5)
		"headline_unavailable": "because of GDPR consent first", (6)
		"tags": {  }
1 Meta-Press.es remplacera le jeton {#} par le nombre maximum de résultats à lire depuis cette source (se sera bientôt réglable depuis les paramètres de l’extension, et c’est pour l’instant 20).
2 Pour cet exemple, l’URL a été coupée (car elle était trop longue) mais j’ai laissé le paramètre GET sort=displaydatetime desc car il est important d’obtenir des résultats triés les plus récents en premier
3 Lorsqu’on analyse un objet JSON, on peut préciser un chemin pour accéder à un sous élément (dans le plus pur style JavaScript de notation pointée)
4 Ce chemin mène à la liste des résultats, Meta-Press.es va la parcourir.
5 Ces deux lignes sont en fait tirée de la définition de source "https://www.arretsurimages.net". L’entrée r_by pointe une liste JSON et l’entrée r_by_attr désigne un attribut des objets de la liste. Meta-Press.es formera donc une chaîne de caractère en rassemblant l’attribut en question de chaque élément de la liste pointée. On récupère ici en pratique la liste complète des auteurs.
6 Il n’y a pas d’entrée headline_url dans cette définition, mais une entrée au nom arbitraire à la place, afin d’expliquer pourquoi on n’essayera pas de charger de gros titre pour cette entrée. L’idée étant de faciliter le travail de développeur qui essayera de corriger le problème.

3.3.4. Définition de source basées sur des sélecteurs CSS

	"https://www.mediapart.fr": {
		"headline_url": "https://www.mediapart.fr",
		"headline_selector": ".une-block h3 a", (1)
		"search_url": "https://www.mediapart.fr/search?search_word=\"{}\"&sort=date&order=desc",
		"res_nb": ".sub-title",
		"res_nb_re": ["^(\\d+) ", "$1"], (2)
		"results": "ul.search > li", (3)
		"r_h1": "h2",
		"r_url": "h2 a",
		"r_url_attr": "href", (4)
		"r_dt": "span.author",
		"r_dt_re": ["\\s(\\d+)[erèm]* (.+) (\\d{4})", "$3-{$2}-$1"], (5)
		"r_txt": "p",
		"r_by": ".author a[rel=author]",
		"tags": {  }
	},
1 Ce sélecteur de gros-titre doit pointer vers un lien, si possible le plus gros titre à la une du journal.
2 res_nb peut lui aussi être accompagné d’une entrée complémentaire _re, ici cela permet d’extraire le nombre de résultats au début d’une chaîne plus grande
3 Ici l’application globale du sélecteur results sur la page de résultats abouti à la liste à parcourir. Notons l’utilisation d’un sélecteur CSS strict (avec >) pour s’assurer qu’on n’attrapera pas des éléments indésirés éventuellement présents ailleurs sur la page
4 r_url_attr permet de cibler l’attribut href
5 r_dt_re
  • Ici nous capturons les différents éléments de la date pour les remettre dans l’ordre attendu par JavaScripti. De plus le nom du mois est entouré d’accolades dans le motif de remplacement {$2} et il sera donc converti dans son numéro de mois grâce à la fonction month_nb. Cette fonction permet de convertir les noms de mois de 69 langues en leur numéros, sans avoir besoin de connaître la langue en question.

  • On peut ensuite noter que la barre oblique (ou slash) est le caractère d’échappement en JavaScript, et qu’il est du coup nécessaire de l’échapper lui-même pour l’encoder dans une chaîne, d’où les : \\s et \\d.

3.3.5. Définition de source basées sur la méthode HTTP POST

	"https://the-japan-news.com": {
		"headline_url": "https://the-japan-news.com",
		"headline_selector": "#topNewsWrapper a",
		"favicon_url": "https://the-japan-news.com/favicon.ico",
		"method": "POST", (1)
		"body": "siteSearchInput={}&x=7&y=11&span=365", (2)
		"search_url": "https://the-japan-news.com/news/search",
		
		"r_dt": "time", (3)
		"r_dt_attr": "datetime", (3)
		
	}
1 En plus de l’habituel search_url, il y a ici besoin de l’entrée method positionnée à POST
2 Et d’un body pour la requête. C’est une chaîne de caractère l’équivallente à la query string des paramètres de requête GET.
3 On peut noter que quand une balise HTML <time datetime=""> est présente il est préférable de l’utiliser car elle évite d’avoir a reformater la date à l’aide d’un motif de remplacement, et aussi d’avoir à préciser le fuseau horaire de la source dans les tags.

3.3.6. Définition de source basée des chemins XPath

XPath est un language très puissant et peut être utilisé pour remplacer tous les sélecteurs CSS.

   "https://www.helsinkitimes.fi": {
		"headline_url": "https://www.helsinkitimes.fi",
		"headline_selector": "h2[itemprop=\"headline\"] a",
		"search_url": "https://www.helsinkitimes.fi/search1332318146.html?searchword={}&ordering=newest&searchphrase=all&limit={#}", (1)
		"res_nb": ".searchintro .bagde",
		"results": ".result-title",
		"r_h1": "a",
		"r_url": "a",
		"r_url_attr": "href",
		"r_dt_xpath": "./following-sibling::dd[@class=\"result-created\"][1]/strong", (2)
		"r_txt_xpath": "./following-sibling::dd[@class=\"result-text\"][1]",
		"r_by_xpath": "./following-sibling::dd[@class=\"result-category\"][1]/span",
		"tags": {  }
	}
1 Comme pour le WaPo et sa réponse en JSON, the Helsinky Times permet de préciser combien de résultats nous voulons en réponse à notre requête. Meta-Press.es remplacera le jeton {#} par le nombre de résultats voulus (20 par défaut).
2 À la place d’une entrée r_dt normale, ici on a une entrée r_dt_xpath. Ce champs n’est donc pas défini par un sélecteur CSS mais par un sélecteur de chemin XPath. Dans ce cas précis, cela nous permet de désigner l’élément suivant relativement à l’élément courant, ce qui n’est pas possible en CSS.

On peut également noter que :

  • XPath permet d’atteindre l’élément parent de l’élément courant, ce qui n’est pas non plus possible en CSS.

  • XPath est également nécessaire pour désigner des balises XML dont le nom fait partie d’un espace de nommage, comme c’est le cas du champs Auteur de la plupart des flux RSS (étendus via la DTD Dublin Core).

3.4. Expressions Rationnelles

Les expressions rationnelles (ou régulières, RegEx) sont un sujet complexe. Voici à nouveau un peu de documentation à ce propos : Expressions Régulières.

Si vous avez déjà travaillé avec des RegEx voici un rappel des quelques points à garder en tête concernant l’usage qui en est fait avec Meta-Press.es :

  • les motifs de reconnaissance doivent être délimités de chaque côté pour attraper tout et non pas une partie seulement de ce que vous souhaitez, par exemple ici : "\\s(\\d+)\\s" il y a n’importe quel blanc (\s espace ou tabulation) avant et après le groupe de chiffres à attraper.

  • vous aurez principalement besoin de : \d+ \w+ \s+ (pour décrire des nombres, des mots et des blancs)

  • ensuite vous aurez principalement besoin de : () ()? (?:) pour extraire les motifs entre parenthèse, spécifier des motifs facultatifs suivit d’un ? et spécifier un motif à ne pas extraire, avec ?: au début de la parenthèse.

Les motifs à extraire sont ré-injectables dans le motif de remplacement via l’expression $1 pour le premier motif entre parenthèses, $2 pour le suivant…

3.5. Format de date

Meta-Press.es accepte tous les formats de date supportés par l’instruction JavaScript : new Date("date string"). De plus, les dates relatives anglaises telles que 2 minutes ago, 8 hours ago et même today, yesterday et new sont supportées.

Pour les sources d’autres langues, les dates doivent être converties dans l’un des formats acceptés par JavaScript, tels que les formats anglais et ISO : aaaa/mm/jj hh:mm:ss tz. Cela peut être fait en spécifiant un motif de remplacement par expression rationnelle via r_dt_re ("$3-($2)-$1") et en ajoutant des accolades autour des noms de mois à convertir en numéro (voir le 4e point de l' exemple à base de sélecteur CSS). Dans ce cas, c’est la fonction month_nb qui fera la conversion. Elle peut convertir tous les noms de mois d’à peu près toutes les langues en leur numéro, à partir seulement du nom du mois en question (en UTF-8).

Enfin, concernant les fuseaux horaires, Meta-Press.es utilise la fonction timezoned_date() du fichiers js/utils.js, elle-même construite autour de la récente fonction toLocaleTimeString() pour créer des dates appartenant à un fuseau horaire précis (celui fourni par l’entrée "tz" des "tags". Une fonction native de l’API JavaScript serait bienvenue dans ce domaine.

3.6. Tags

Il est impératif de reproduire au moins l’ensemble suivant d’étiquettes de classement (ou tags) pour chaque source définie.

Les suivants sont ceux de la source 'Mediapart.fr/en' :

"tags": {
	"name": "Mediapart.fr",
	"lang": "fr",
	"country": "fr",
	"themes": ["general", "politics"],
	"tech": ["OR", "own search", "fast"], (1)
	"src_type": ["press", "reference press"],
	"res_type": "text",
	"scope": "International",
	"freq": "daily",
	"tz": "Europe/Paris" (2)
}
1 Les étiquettes de l’entrée "tech" fonctionnent principalement par paires :
  • AND ou OR dépend de la capacité de la source à établir la connexion logique spécifiée ("ET" ou "OU") entre les différents termes d’une recherche. L’objectif est d’avoir un maximum de AND et c’est un des fitres par défaut, mais quand ce n’est pas possible, on affuble la source de l’étiquette AND pour pouvoir l’utiliser quand même dans certains cas.

  • fast ou slow dépend pour l’instant de la vitesse de chargement des résultats à froid sur le poste du développeur principal. Si les résultats mettent moins de 3s à arriver alors l’étiquette fast est attribuée. Il est prévu d’implémenter un test de vitesse à lancer sur le poste de chaque utilisateur afin d’avoir une meilleur répartition.

  • own search ou external search se réfère au moteur de recherche mis en œuvre par la source. Si la source utilise un prestataire externe (comme Google News) alors l’étiquette own search ne doit pas lui être attribuée. En pratique pour l’instant le développeur principal n’intègre pas de sources à recherche externe. C’est pourquoi le Guardian n’est pas encore disponible, mais on espère beaucoup qu’ils reprennent les choses en mains.

  • HTTPS / HTTP est une étiquette calculée automatiquement au chargement des sources. Elle permet de ne chercher par défaut que dans les sources offrant le niveau de confidentialité atteint par le chiffrement du protocole HTTPS.

  • l’étiquette broken permet d’éviter une source (par exemple si elle vient d’être rapportée comme étant défectueuse) elle n’est alors plus disponible.

2 Le fuseau horaire tz est une étiquette utile seulement si la date lisible dans les résultats ne comporte pas déjà cette information.