2017-10-12 5 views
0

donc j'utilise Cheerio, une bibliothèque similaire à jQuery sur le côté serveur de nœud , qui vous permet d'analyser un texte html et traverse c'est exactement comme avec jQuery. J'ai besoin d'obtenir le texte brut du corps html, mais pas seulement cela, j'ai besoin d'obtenir l'élément et le numéro correspondant. IE: si le texte brut a été trouvé dans le troisième élément de paragraphe, j'aurais quelque chose comme:DOM traversal avec cheerio - Comment obtenir tous les éléments avec leur texte correspondant

{ 
    text: <element plaintext>, 
    element: "p-3" 
} 

J'ai actuellement la fonction suivante qui tente de le faire:

var plaintext_elements = traverse_tree($('body'));  

function traverse_tree(root, found_elements = {}, return_array = []) { 
    if (root.children().length) { 
     //root has children, call traverse_tree on that subtree 
     traverse_tree(root.children().first(), found_elements, return_array); 
    } 
    root.nextAll().each(function(i, elem) { 
     if ($(elem).children().length) { 
      //if the element has children call traverse_tree on the element's first child 
      traverse_tree($(elem).children().first(), found_elements, return_array) 
     } 
     else { 
      if (!found_elements[$(elem)[0].name]) { 
       found_elements[$(elem)[0].name] = 1; 
      } 
      else { 
       found_elements[$(elem)[0].name]++ 
      } 
      if ($(elem).text() && $(elem).text != '') { 
       return_array.push({ 
        text: $(elem).text(), 
        element: $(elem)[0].name + '-' + found_elements[$(elem)[0].name] 
       }) 
      } 
     } 
    }) 


    if (root[0].name == 'body') { 
     return return_array; 
    } 

} 

Est-ce que je vais en la bonne direction, devrais-je essayer autre chose? Toute aide à ce sujet serait appréciée. Encore une fois c'est pas jQuery, mais Cheerio sur le côté serveur. (Ils sont très similaires, cependant)

+0

À partir de votre code actuel, il semble que vous êtes heureux d'ignorer les éléments qui ont enfants et texte? Comme le 'dt' dans'

text

dt
' – Matt

+0

ouais, c'est l'un des problèmes que j'ai rencontrés. Je ne sais pas comment gérer ce cas sans avoir une tonne de doublons, comme dire 'blah blah blah' ramasserait "bla bla bla" pour les deux td et un. – janedoe

Répondre

0

Je pense que beaucoup de traversal n'est pas nécessaire si vous utilisez le sélecteur * css

function textElements($){ 
    const found = {} 
    return $('body *').map(function(el){ 
    if ($(this).children().length || $(this).text() === '') return 
    found[this.name] = found[this.name] ? 1 + found[this.name] : 1 
    return { 
     text: $(this).text(), 
     element: `${this.name}-${found[this.name]}`, 
    } 
    }).get() 
} 

textElements(cheerio.load(html) 
+0

cela semble fonctionner mais il rencontre toujours des problèmes quand le html est quelque chose comme ' bonjour, cliquez ici pour voir nos résultats', il ne prend que "cliquez ici" à partir de là. – janedoe