CheerioJS - Return True if two items present within a div

Viewed 26

I am trying to write a script with Node and Cheerio JS that checks a website and returns true if tickets are available for a certain teams game. The basic HTML structure of the site is

<body>
    <div class="competition">
      <div class="match">
        <div class="team-info">
          <h3>
            <span class="team">Team 1</span>
            <span class="team">Team 2</span>
          </h3>
        </div>
        <div class="buy-info">
          <div class="btn available">Buy</div>
        </div>
      </div>
      <div class="match">
        <div class="team-info">
          <h3>
            <span class="team">Team 3</span>
            <span class="team">Team 4</span>
          </h3>
        </div>
        <div class="buy-info">
          <div class="btn available">Buy</div>
        </div>
      </div>
    </div>
  </body>

I want to use Cheerio and with an each() function, check each match class and return true of 'Team 1' is the text value of the team span and the corresponding Buy button has the class available. I have written the below so far but on my real life example, it is returning the number of total available buttons * the amount of games 'Team 1' play.

const teamFinder = ".team";
// set match day class
    const match = ".match";
    let MatchCount = 0;

    $(match).each((MDIdx, MDElm) => {
      $(teamFinder).each((parentIdx, parentElm) => {
        let team = $(parentElm).text();

        if (team == "Team 1") {
          if ($(buttonDiv).children().hasClass("available")) {
            MatchCount++;
          }
        }
      });
    });
1 Answers

I think your issue is that your inner each() iterates over all elements found in html, and not current .match div. so, instead of: $(teamFinder).each()

you should use: $(teamFinder, MDElm).each()

Here is the fixed example: https://scrapeninja.net/cheerio-sandbox?slug=b9db2202ea00e21f7d7197b1667802edd411ea33

a "cleaner" approach:

// define function which accepts body and cheerio as args
function extract(input, cheerio) {
    // return object with extracted values              
    let $ = cheerio.load(input);

    // extract all matches
    let matches = $('.match').map((k, v) => {
        return {
            teams: $('.team', v).map((k, v) => $(v).text().trim()).toArray(),
            available: $('.buy-info .available', v).length
        }
    }).toArray();

    // pure JSON with matches
    console.log(matches);

    let matchCount = matches.filter(m => m.teams.includes('Team 1') && m.available).length;
    console.log(`matchCount: ${matchCount}`);
}

https://scrapeninja.net/cheerio-sandbox?slug=2b6fd73137469289934c42294bba18fa1cbfa355

Related