3
\$\begingroup\$

I already posted a not (yet) complete version of this class, but that question got closed, because it contained not passing tests. Here is the full version, all 5 tests pass.

Originally there was only processPlayer when I found a very rare case (see the last test Special case). The method player is a patch to handle this kind of cases. Maybe the two method could be merged.

class Scraper {
  /**
   * Converts a html string to a cheerio object
   * @param {String} html The html string
   * @return {Object} The cheerio object
   */
  htmlToDom(html) {
    return cheerio.load(html)
  }

  // http://jsbin.com/nojedozaxo/1/edit?js,console,output
  player(href, name) {
    let p = name.replace(/\./g, '.+')
    let r = new RegExp(".+(" + p + ")-.+", 'i')
    let R = href.match(r)[1].split('-')
      .map(w => w.charAt(0).toUpperCase() + w.slice(1))
    return {
      firstName: R[2],
      lastName: R.slice(0, 2).join('-')
    }
  }

  processPlayers(players) {
    // is it a selector function or an object
    players = typeof players === 'function' ? players('a') : players.find('a')
    let href = players.attr('href')
    let N = players.text().trim().split(/\s+-\s+/).map(n => {
      if (n.indexOf(' ') === -1) {
        return this.player(href, n)
      }
      let r = new RegExp('.+(' + n.replace(/-/g, '\\S+').replace(/\./g, '[^-]+').replace(/\s/g, '.') + ').+', 'i')
      let p = {
        lastName: n.replace(/\s\S+\./g, '')
      }
      href.match(r).map(m => {
        r = new RegExp(p.lastName.replace(/\s/g, '.') + '-', 'i')
        m = m.replace(r, '').split(/-/).map(i => {
          return i.substring(0, 1).toUpperCase() + i.substring(1)
        })
        p.firstName = n.split(p.lastName + ' ')[1].replace(/[a-z]*\./g, '').split('').map(l => {
          return m[0] && m[0].indexOf(l) === 0 ? m.shift() : l
        }).join('')
      })
      return p
    })
    return {
      p1: N[0],
      p2: N[1]
    }
  }
}

// test ===========================================================

test('simple case', function() {
  let playersCell = `
    <td>
      <a href="/t/pavlyuchenkova-anastasia-sorribes-tormo-sara/">
        <span>Pavlyuchenkova A.</span>
         - Sorribes Tormo S.
       </a>
    </td>
    `
  const scraper = new Scraper()
  const td = scraper.htmlToDom(playersCell)
  const players = scraper.processPlayers(td)

  equal(players.p1.firstName, 'Anastasia')
  equal(players.p1.lastName, 'Pavlyuchenkova')

  deepEqual(players.p2, {
    firstName: 'Sara',
    lastName: 'Sorribes Tormo',
  })
});

// =====================================================================

test('hyphen in last name', function() {
  let playersCell = `
    <td><a href="/t/kudermetova-veronika-duque-marino-mariana/">
      <span>Kudermetova V.</span> - Duque-Marino M.</a>
    </td>
    `
  const scraper = new Scraper()
  const td = scraper.htmlToDom(playersCell)
  const players = scraper.processPlayers(td)

  equal(players.p2.firstName, 'Mariana')
  equal(players.p2.lastName, 'Duque-Marino')
});

// =====================================================================

test('hyphen in first name', function() {
  let playersCell = `
    <td>
      <a href="/t/tsonga-jo-wilfried-mayer-florian/">
        <span>Tsonga J-W.</span>
        - Mayer F.
      </a>
    </td>
    `
  const scraper = new Scraper()
  const td = scraper.htmlToDom(playersCell)
  const players = scraper.processPlayers(td)

  equal(players.p1.firstName, 'Jo-Wilfried')
  equal(players.p1.lastName, 'Tsonga')
});

test('two first names', function() {
  let playersCell = `
      <td>
        <a href="/t/alexandrova-ekaterina-muguruza-blanco-garbine/">
        Alexandrova E. - <span>Muguruza</span> B. G.</a>
      </td>
    `
  const scraper = new Scraper()
  const td = scraper.htmlToDom(playersCell)
  const players = scraper.processPlayers(td)

  equal(players.p2.firstName, 'Blanco Garbine')
  equal(players.p2.lastName, 'Muguruza')
});

// =====================================================================

test('short first name has two letters', t => {
  let playersCell = `
    <a href="/t/pliskova-kristyna-babos-timea/">
      <span class="bold">Pliskova Kr.</span> - Babos T.</a>`
  const scraper = new Scraper()
  const td = scraper.htmlToDom(playersCell)
  const players = scraper.processPlayers(td)

  equal(players.p1.firstName, 'Kristyna')
  equal(players.p1.lastName, 'Pliskova')
})

// =====================================================================
test('special case', t => {
  let playersCell = `
    <a href="/t/kovalik-jozef-ramirez-hidalgo-ruben-sdgdsg/">
    <span class="bold">Kovalik J.</span> - Ramirez-H.R.</a>
    `
  const scraper = new Scraper()
  const td = scraper.htmlToDom(playersCell)
  const players = scraper.processPlayers(td)

  equal(players.p2.firstName, 'Ruben')
  equal(players.p2.lastName, 'Ramirez-Hidalgo')
});
<script src="https://wzrd.in/standalone/cheerio@latest"></script>
<script src="https://code.jquery.com/qunit/qunit-1.12.0.js"></script>
<link href="https://code.jquery.com/qunit/qunit-1.12.0.css" rel="stylesheet" />

<div id="qunit"></div>
<div id="qunit-fixture"></div>

Here is an alternative JsBin: http://jsbin.com/sizocatizi/1/edit?html,js,output

\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.