Quel algorithme utilise Readability pour extraire du texte des URL?


102

Depuis un certain temps, j'essaie de trouver un moyen d'extraire intelligemment le texte "pertinent" d'une URL en éliminant le texte lié aux publicités et tout le reste du désordre. Après plusieurs mois de recherche, je l'ai abandonné comme un problème cela ne peut être déterminé avec précision. (J'ai essayé différentes manières mais aucune n'était fiable)

Il y a une semaine, je suis tombé sur Readability - un plugin qui convertit n'importe quelle URL en texte lisible. Cela me semble assez précis. Je suppose qu'ils ont en quelque sorte un algorithme suffisamment intelligent pour extraire le texte pertinent.

Quelqu'un sait-il comment il le fait? Ou comment pourrais-je le faire de manière fiable?


3
La question est de savoir quel algorithme utilise SO pour que Readability ne gère pas ses pages? :)
Piotr Dobrogost

Réponses:


170

La lisibilité consiste principalement en des heuristiques qui "fonctionnent bien" dans de nombreux cas.

J'ai écrit quelques articles de recherche sur ce sujet et je voudrais expliquer pourquoi il est facile de trouver une solution qui fonctionne bien et quand il devient difficile de se rapprocher de 100% de précision.

Il semble y avoir une loi linguistique sous-jacente au langage humain qui se manifeste également (mais pas exclusivement) dans le contenu des pages Web, qui sépare déjà assez clairement deux types de texte (texte intégral ou non intégral ou, grosso modo, " contenu principal "vs" passe-partout ").

Pour obtenir le contenu principal du HTML, il suffit dans de nombreux cas de ne conserver que les éléments de texte HTML (c'est-à-dire des blocs de texte qui ne sont pas interrompus par du balisage) qui comptent plus de 10 mots environ. Il semble que les humains choisissent entre deux types de texte («court» et «long», mesurés par le nombre de mots qu'ils émettent) pour deux motivations différentes d'écriture de texte. Je les appellerais des motivations «de navigation» et «d'information».

Si un auteur veut vous rapidement obteniez ce qui est écrit, il utilise du texte "de navigation", c'est-à-dire quelques mots (comme "STOP", "Lisez ceci", "Cliquez ici"). C'est le type de texte le plus important dans les éléments de navigation (menus, etc.)

Si un auteur veut que vous compreniez profondément ce qu'il veut dire, il utilise de nombreux mots. De cette manière, l'ambiguïté est levée au prix d'une augmentation de la redondance. Le contenu de type article appartient généralement à cette classe car il ne contient que quelques mots.

Bien que cette séparation semble fonctionner dans une pléthore de cas, elle devient délicate avec les titres, les phrases courtes, les clauses de non-responsabilité, les pieds de page de copyright, etc.

Il existe des stratégies et des fonctionnalités plus sophistiquées qui aident à séparer le contenu principal du passe-partout. Par exemple, la densité des liens (nombre de mots dans un bloc qui sont liés par rapport au nombre total de mots dans le bloc), les caractéristiques des blocs précédents / suivants, la fréquence d'un texte de bloc particulier dans le Web «entier», le Structure DOM du document HTML, image visuelle de la page, etc.

Vous pouvez lire mon dernier article " Détection de plaques chauffantes à l'aide des fonctionnalités de texte peu profond " pour obtenir un aperçu d'un point de vue théorique. Vous pouvez également regarder la vidéo de ma présentation sur VideoLectures.net.

La «lisibilité» utilise certaines de ces fonctionnalités. Si vous regardez attentivement le journal des modifications SVN, vous verrez que le nombre de stratégies variait au fil du temps, tout comme la qualité d'extraction de Readability. Par exemple, l'introduction de la densité de liens en décembre 2009 a beaucoup contribué à l'amélioration.

À mon avis, cela n'a donc aucun sens de dire "La lisibilité fait comme ça", sans mentionner le numéro de version exact.

J'ai publié une bibliothèque d'extraction de contenu HTML Open Source appelée Chaudière , qui fournit plusieurs stratégies d'extraction différentes. Selon le cas d'utilisation, l'un ou l'autre des extracteurs fonctionne mieux. Vous pouvez essayer ces extracteurs sur les pages de votre choix à l'aide de l'application Web-chaudière compagnon sur Google AppEngine.

Pour laisser parler les nombres, consultez la page " Benchmarks " sur le wiki de la chaudière qui compare certaines stratégies d'extraction, y compris la chaudière, la lisibilité et Apple Safari.

Je dois mentionner que ces algorithmes supposent que le contenu principal est en fait du texte intégral. Il y a des cas où le "contenu principal" est autre chose, par exemple une image, un tableau, une vidéo, etc. Les algorithmes ne fonctionneront pas bien dans de tels cas.

À votre santé,

Christian


3
Ce projet de chaudière est-il toujours actif?
Abby

5
Je pense que vous feriez mieux de mettre votre projet sur GitHub afin qu'il se développe socialement par les développeurs open source.
Inanc Gumus

1
Un bon exemple de l'explication du Dr Kohlschütter est en fait cette page Web, dans Safari, si vous avez utilisé le Reader, vous constaterez que sa réponse est affichée comme texte principal, grâce à la densité des liens. C'est du texte lié, donc reconnu comme texte principal, par rapport à d'autres blocs.
Abdelrahman Eid

1
"Migré" une copie dans mon repo github.com/k-bx/boilerpipe juste au cas où il se perdrait :)
Konstantine Rybnikov

16

la lisibilité est un bookmarklet javascript. signifiant son code côté client qui manipule le DOM. Regardez le javascript et vous devriez être en mesure de voir ce qui se passe.

Flux de travail et code de lisibilité:

/*
     *  1. Prep the document by removing script tags, css, etc.
     *  2. Build readability's DOM tree.
     *  3. Grab the article content from the current dom tree.
     *  4. Replace the current DOM tree with the new one.
     *  5. Read peacefully.
*/

javascript: (function () {
    readConvertLinksToFootnotes = false;
    readStyle = 'style-newspaper';
    readSize = 'size-medium';
    readMargin = 'margin-wide';
    _readability_script = document.createElement('script');
    _readability_script.type = 'text/javascript';
    _readability_script.src = 'http://lab.arc90.com/experiments/readability/js/readability.js?x=' + (Math.random());
    document.documentElement.appendChild(_readability_script);
    _readability_css = document.createElement('link');
    _readability_css.rel = 'stylesheet';
    _readability_css.href = 'http://lab.arc90.com/experiments/readability/css/readability.css';
    _readability_css.type = 'text/css';
    _readability_css.media = 'all';
    document.documentElement.appendChild(_readability_css);
    _readability_print_css = document.createElement('link');
    _readability_print_css.rel = 'stylesheet';
    _readability_print_css.href = 'http://lab.arc90.com/experiments/readability/css/readability-print.css';
    _readability_print_css.media = 'print';
    _readability_print_css.type = 'text/css';
    document.getElementsByTagName('head')[0].appendChild(_readability_print_css);
})();

Et si vous suivez les fichiers JS et CSS que le code ci-dessus extrait, vous aurez une vue d'ensemble:

http://lab.arc90.com/experiments/readability/js/readability.js (c'est assez bien commenté, lecture intéressante)

http://lab.arc90.com/experiments/readability/css/readability.css


12

Il n'y a pas de moyen fiable à 100% de le faire, bien sûr. Vous pouvez consulter le code source de la lisibilité ici

Fondamentalement, ils essaient d'identifier des blocs de texte positifs et négatifs . Les identifiants positifs (c'est-à-dire les identifiants div) seraient quelque chose comme:

  • article
  • corps
  • contenu
  • Blog
  • récit

Les identifiants négatifs seraient:

  • commentaire
  • discuter

Et puis ils ont des candidats peu probables et peut - être . Ce qu'ils feraient est de déterminer ce qui est le plus susceptible d'être le contenu principal du site, voir la ligne 678dans la source de lisibilité. Cela se fait en analysant principalement la longueur des paragraphes, leurs identifiants (voir ci-dessus), l'arborescence DOM (c'est-à-dire si le paragraphe est un dernier nœud enfant), en supprimant tout ce qui n'est pas nécessaire, en supprimant le formatage, etc.

Le code comporte 1792 lignes. Cela semble être un problème non trivial, alors peut-être pouvez-vous vous inspirer de là.


2
Savez-vous si leur code est open source et s'il peut être utilisé dans des produits commerciaux?
user300981

2
Il dit que le code source est publié sous licence Apache 2.0, ce qui signifie que vous pouvez l'utiliser, le distribuer, le modifier et en distribuer des versions modifiées. Je ne suis pas trop clair sur les détails cependant.
slhck

2
@bobsmith Apple l'a utilisé dans la dernière version de Safari. Ils ont crédité Arc90 dans les notes de publication.
s4y

7

Intéressant. J'ai développé un script PHP similaire. Il scanne essentiellement les articles et joint des parties du discours à tout le texte (Brill Tagger). Ensuite, les phrases grammaticalement invalides sont instantanément éliminées. Ensuite, des changements soudains dans les pronoms ou le passé indiquent que l'article est terminé ou n'a pas encore commencé. Les expressions répétées sont recherchées et éliminées, comme "Yahoo News Sports Finance" apparaît dix fois dans la page. Vous pouvez également obtenir des statistiques sur le ton avec une pléthore de banques de mots relatives à diverses émotions. Des changements soudains de ton, d'actif / négatif / financier, à passif / positif / politique indiquent une frontière. C'est vraiment sans fin, quelle que soit la façon dont vous voulez creuser.

Les principaux problèmes sont les liens, les anomalies intégrées, les styles de script et les mises à jour.


3
Cela ressemble en fait à une approche vraiment intéressante - avez-vous du code à partager?
LSG

2
Je confirme que, avez-vous des exemples de code ou des informations entourant votre code que nous pouvons examiner?
userabuser
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.