Created KissAsianScraper.

This commit is contained in:
2021-06-11 22:19:34 -05:00
parent 07f2932477
commit 7467b699df
8 changed files with 1189 additions and 1 deletions

View File

@@ -0,0 +1,115 @@
const Logger = require('../utils/Logger');
const { ScraperError } = require('../../errors');
class KissAsianScraper {
constructor(page) {
this.page = page;
}
async load() {
await this.page.goto(KissAsianScraper.BASE_URL);
await this.page.waitForSelector(KissAsianScraper.DEFAULTS.SITE_SELECTOR);
Logger.info('Cloudflare DDOS Protection bypassed, redirected to main site.');
}
async authenticate(credentials) {
await this.page.click('#topHolderBox a[href="/Login"]');
await this.page.waitForSelector('#btnSubmit');
Logger.info('Authenticating...');
await this.page.$eval('#username', (el, credentials) => el.value = credentials.username, credentials);
await this.page.$eval('#password', (el, credentials) => el.value = credentials.password, credentials);
await this.page.click('#btnSubmit');
await this.page.waitForSelector('#head a.logo');
Logger.success(`Successfully logged in as ${credentials.username}.`);
}
async getMediaLinks(mediaURL) {
await this.page.goto(mediaURL);
await this.page.waitForSelector(KissAsianScraper.DEFAULTS.SITE_SELECTOR);
Logger.info(`Visited ${mediaURL}`);
Logger.info('Getting media links...');
const links = await this.page.evaluate(() => {
const table = document.querySelector('.episodeList table.listing');
const tableBody = table.firstElementChild;
const links = [];
for (let i = tableBody.children.length - 1; i > 1; i--) {
const node = tableBody.children.item(i);
const aElement = node.firstElementChild.firstElementChild;
links.push(aElement.href);
}
return links;
});
Logger.success(`Scraped ${links.length} media links.`);
return links;
}
async directlyVisitPlayerURL(playerURL) {
await this.page.goto(`${playerURL}&s=mp`);
await this.page.waitForSelector(KissAsianScraper.DEFAULTS.SITE_SELECTOR);
const isCaptchaEnabled = await this.page.evaluate(() => {
const form = document.getElementById('formVerify');
return !!form;
});
if (isCaptchaEnabled) {
throw new ScraperError(`MP server not available for ${playerURL}`);
}
Logger.info(`Directly visited ${playerURL}`);
}
async getDownloadLinkForCurrentPlayer() {
return await this.page.evaluate(() => {
const divDownload = document.getElementById('divDownload');
const aElement = divDownload.lastElementChild;
return aElement.href;
});
}
async skipCaptcha(playerURL) {
Logger.warn('Skipping captcha...');
const [skipCaptchaButton] = await this.page.$x('//a[contains(., "FE server")]');
if (!skipCaptchaButton) {
throw new ScraperError(`Skip captcha button not found for ${playerURL}`);
}
await skipCaptchaButton.click();
await this.page.waitForSelector(KissAsianScraper.DEFAULTS.SITE_SELECTOR);
Logger.success('Successfully skipped captcha.');
}
async selectEpisodeServerForCurrentPlayer(server) {
try {
await this.page.select('#selectServer', server);
await this.page.waitForSelector(KissAsianScraper.DEFAULTS.SITE_SELECTOR);
Logger.info(`Changed streaming server to ${server}.`);
} catch (err) {
throw new ScraperError(`Server ${server} is unavailable.`);
}
}
}
KissAsianScraper.BASE_URL = 'https://kissasian.li';
KissAsianScraper.DEFAULTS = {
SITE_SELECTOR: '#head a.logo'
};
module.exports = KissAsianScraper;

View File

@@ -0,0 +1,21 @@
const chalk = require('chalk');
class Logger {
static info(...args) {
console.info(chalk.blue(...args));
}
static error(...args) {
console.error(chalk.red(...args));
}
static success(...args) {
console.log(chalk.green(...args));
}
static warn(...args) {
console.warn(chalk.yellow(...args));
}
}
module.exports = Logger;

9
src/errors/FatalError.js Normal file
View File

@@ -0,0 +1,9 @@
class FatalError extends Error {
constructor(message) {
super(message);
this.name = 'FatalError';
}
}
module.exports = FatalError;

View File

@@ -0,0 +1,9 @@
class ScraperError extends Error {
constructor(message) {
super(message);
this.name = 'ScraperError';
}
}
module.exports = ScraperError;

7
src/errors/index.js Normal file
View File

@@ -0,0 +1,7 @@
const FatalError = require('./FatalError');
const ScraperError = require('./ScraperError');
module.exports = {
FatalError,
ScraperError
};

24
src/index.js Normal file
View File

@@ -0,0 +1,24 @@
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const AdBlockerPlugin = require('puppeteer-extra-plugin-adblocker');
const KissAsianScraper = require('./classes/scraping/KissAsianScraper');
const credentials = require('../data/credentials.json');
puppeteer.use(StealthPlugin());
puppeteer.use(AdBlockerPlugin({ blockTrackers: true }));
const main = async() => {
const browser = await puppeteer.launch({ headless: false, slowMo: 250 });
const page = await browser.newPage();
const scraper = new KissAsianScraper(page);
await scraper.load();
await scraper.authenticate(credentials.kissasian);
const links = await scraper.getMediaLinks('https://kissasian.li/Drama/My-Roommate-is-a-Gumiho');
await scraper.directlyVisitPlayerURL(links[0]);
console.log(await scraper.getDownloadLinkForCurrentPlayer());
};
main();