how to filter cheerio objects in `each` with selec

2019-07-09 23:31发布

问题:

I'm parsing a simple webpage using Cheerio and I was wandering if possible is follwing:

With a html of this structure:

<tr class="human">
    <td class="event"><a>event1</a></td>
    <td class="name">name1</td>
    <td class="surname"><a>surname1</a></td>
    <td class="date">2011</td>
</tr>
<tr class="human">
    <td class="event"><a>event2</a></td>
    <td class="name">name2</td>
    <td class="surname"><a>surname2</a></td>
    <td class="date">2012</td>
</tr>
<tr class="human">
    <td class="event"><a>event3</a></td>
    <td class="name">name3</td>
    <td class="surname"><a>surname3</a></td>
    <td class="date">2013</td>
</tr>

Once I get all the cheerio objects which match the tr.human selector I want to be able to loop through them to map values in classes name, surname etc. to an object.

So far I achieved this:

var cheerio = require('cheerio');
var fs = require('fs')

fs.readFile('./humans.html', 'utf8', function (err,data) {
    if (err) {
        return console.log(err);
    }

    const $ = cheerio.load(data)
    var results = $('tr.human')

    results.each(function(i, result){

       var date = result.children[3]
       var name = result.children[1]
       var surname = result.children[2]

       var object = {"name":name,"date":date,"surname":surname}
   })
});

But I want to get rid of calling to index in children, instead I would like to filter result by a selector, something like this:

var date = result.children('td.date')

but above results in following error:

var date = result.children('td.date')
                          ^
TypeError: result.children is not a function

I'm new to node and cheerio, read the Cheerio docs, but I'm pretty stuck with this one. How could I get the values under certain classes with usage of selectors?

I must admit that I want first loop through elements and inside each iteration map to object, not to match selectors and then loop as probably this doesn't guarantee proper order of elements in matched results (loop and filter is not commutative here), or it does?

回答1:

result is a bare element, not wrapped in cheerio. Similar to jQuery, you might want to wrap it again in $()

var date = $(result).children('td.date');