@johndoeantler/mal-scraper
Version:
Scrap everything you can from MyAnimeList.net
105 lines (86 loc) • 2.93 kB
JavaScript
const axios = require('axios')
const cheerio = require('cheerio')
const { getResultsFromSearch } = require('./info.js')
const BASE_URI = 'https://myanimelist.net/anime/'
const malNumberToJsNumber = (malNumber) => {
if (malNumber) {
malNumber = malNumber.replace(/\D/gi, '')
return Number(malNumber)
}
return 0
}
const parsePage = ($) => {
const stats = $('#content table td:nth-child(2) .spaceit_pad')
const summaryStats = stats.slice(0, 6)
const scoreStats = stats.slice(6)
const scoreStatsLength = scoreStats.length
const result = {}
summaryStats.each(function (elem) {
$(this).find('span').remove()
})
result.watching = malNumberToJsNumber($(summaryStats[0]).text())
result.completed = malNumberToJsNumber($(summaryStats[1]).text())
result.onHold = malNumberToJsNumber($(summaryStats[2]).text())
result.dropped = malNumberToJsNumber($(summaryStats[3]).text())
result.planToWatch = malNumberToJsNumber($(summaryStats[4]).text())
result.total = malNumberToJsNumber($(summaryStats[5]).text())
scoreStats.each(function (index) {
result['score' + (scoreStatsLength - index)] = malNumberToJsNumber($(this).find('small').text())
})
return result
}
const searchPage = (url) => {
return new Promise((resolve, reject) => {
axios.get(url)
.then(({ data }) => {
const $ = cheerio.load(data)
const res = parsePage($)
resolve(res)
})
.catch(/* istanbul ignore next */(err) => reject(err))
})
}
const getStatsFromName = (name) => {
return new Promise((resolve, reject) => {
getResultsFromSearch(name)
.then((items) => {
const { url } = items[0]
searchPage(`${encodeURI(url)}/stats`)
.then((data) => resolve(data))
.catch(/* istanbul ignore next */(err) => reject(err))
})
.catch(/* istanbul ignore next */(err) => reject(err))
})
}
const getStatsFromNameAndId = (id, name) => {
return new Promise((resolve, reject) => {
searchPage(`${BASE_URI}${id}/${encodeURI(name)}/stats`)
.then((data) => resolve(data))
.catch(/* istanbul ignore next */(err) => reject(err))
})
}
const getStats = (obj) => {
return new Promise((resolve, reject) => {
if (!obj) {
reject(new Error('[Mal-Scraper]: No id nor name received.'))
return
}
if (typeof obj === 'object' && !obj[0]) {
const { id, name } = obj
if (!id || !name || isNaN(+id) || typeof name !== 'string') {
reject(new Error('[Mal-Scraper]: Malformed input. ID or name is malformed or missing.'))
return
}
getStatsFromNameAndId(id, name)
.then((data) => resolve(data))
.catch(/* istanbul ignore next */(err) => reject(err))
} else {
getStatsFromName(obj)
.then((data) => resolve(data))
.catch(/* istanbul ignore next */(err) => reject(err))
}
})
}
module.exports = {
getStats
}