aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/parsers/homePage.ts183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/parsers/homePage.ts b/src/parsers/homePage.ts
new file mode 100644
index 0000000..1c3acd0
--- /dev/null
+++ b/src/parsers/homePage.ts
@@ -0,0 +1,183 @@
+import axios, { AxiosError } from "axios";
+import { load, CheerioAPI, SelectorType } from "cheerio";
+import {
+ SRC_HOME_URL,
+ ACCEPT_HEADER,
+ USER_AGENT_HEADER,
+ ACCEPT_ENCODING_HEADER,
+ extractTop10Animes,
+ extractAnimes,
+} from "../utils";
+
+import createHttpError, { HttpError } from "http-errors";
+import { ScrapedHomePage } from "../models";
+
+// /anime/home
+async function scrapeHomePage(): Promise<ScrapedHomePage | HttpError> {
+ const res: ScrapedHomePage = {
+ spotlightAnimes: [],
+ trendingAnimes: [],
+ latestEpisodeAnimes: [],
+ topUpcomingAnimes: [],
+ top10Animes: {
+ today: [],
+ week: [],
+ month: [],
+ },
+ topAiringAnimes: [],
+ genres: [],
+ };
+
+ try {
+ const mainPage = await axios.get(SRC_HOME_URL as string, {
+ headers: {
+ "User-Agent": USER_AGENT_HEADER,
+ "Accept-Encoding": ACCEPT_ENCODING_HEADER,
+ Accept: ACCEPT_HEADER,
+ },
+ });
+
+ const $: CheerioAPI = load(mainPage.data);
+
+ const spotlightSelector: SelectorType =
+ "#slider .swiper-wrapper .swiper-slide";
+
+ $(spotlightSelector).each((i, el) => {
+ const otherInfo = $(el)
+ .find(".deslide-item-content .sc-detail .scd-item")
+ .map((i, el) => $(el).text().trim())
+ .get();
+
+ res.spotlightAnimes.push({
+ rank:
+ Number(
+ $(el)
+ .find(".deslide-item-content .desi-sub-text")
+ ?.text()
+ .trim()
+ .split(" ")[0]
+ .slice(1)
+ ) || null,
+ id: $(el)
+ .find(".deslide-item-content .desi-buttons a")
+ ?.last()
+ ?.attr("href")
+ ?.slice(1)
+ ?.trim(),
+ name: $(el)
+ .find(".deslide-item-content .desi-head-title.dynamic-name")
+ ?.text()
+ .trim(),
+ description: $(el)
+ .find(".deslide-item-content .desi-description")
+ ?.text()
+ ?.split("[")
+ ?.shift()
+ ?.trim(),
+ poster: $(el)
+ .find(".deslide-cover .deslide-cover-img .film-poster-img")
+ ?.attr("data-src")
+ ?.trim(),
+ jname: $(el)
+ .find(".deslide-item-content .desi-head-title.dynamic-name")
+ ?.attr("data-jname")
+ ?.trim(),
+ otherInfo,
+ });
+ });
+
+ const trendingSelector: SelectorType =
+ "#trending-home .swiper-wrapper .swiper-slide";
+
+ $(trendingSelector).each((i, el) => {
+ res.trendingAnimes.push({
+ rank: parseInt(
+ $(el).find(".item .number")?.children()?.first()?.text()?.trim()
+ ),
+ name: $(el)
+ .find(".item .number .film-title.dynamic-name")
+ ?.text()
+ ?.trim(),
+ id: $(el).find(".item .film-poster")?.attr("href")?.slice(1)?.trim(),
+ poster: $(el)
+ .find(".item .film-poster .film-poster-img")
+ ?.attr("data-src")
+ ?.trim(),
+ });
+ });
+
+ const latestEpisodeSelector: SelectorType =
+ "#main-content .block_area_home:nth-of-type(1) .tab-content .film_list-wrap .flw-item";
+ res.latestEpisodeAnimes = extractAnimes($, latestEpisodeSelector);
+
+ const topUpcomingSelector: SelectorType =
+ "#main-content .block_area_home:nth-of-type(3) .tab-content .film_list-wrap .flw-item";
+ res.topUpcomingAnimes = extractAnimes($, topUpcomingSelector);
+
+ const genreSelector: SelectorType =
+ "#main-sidebar .block_area.block_area_sidebar.block_area-genres .sb-genre-list li";
+ $(genreSelector).each((i, el) => {
+ res.genres.push(`${$(el).text().trim()}`);
+ });
+
+ const mostViewedSelector: SelectorType =
+ '#main-sidebar .block_area-realtime [id^="top-viewed-"]';
+ $(mostViewedSelector).each((i, el) => {
+ const period = $(el).attr("id")?.split("-")?.pop()?.trim();
+
+ if (period === "day") {
+ res.top10Animes.today = extractTop10Animes($, period);
+ return;
+ }
+ if (period === "week") {
+ res.top10Animes.week = extractTop10Animes($, period);
+ return;
+ }
+ if (period === "month") {
+ res.top10Animes.month = extractTop10Animes($, period);
+ }
+ });
+
+ const topAiringSelector: SelectorType =
+ "#anime-featured .row div:nth-of-type(1) .anif-block-ul ul li";
+ $(topAiringSelector).each((i, el) => {
+ const otherInfo = $(el)
+ .find(".fd-infor .fdi-item")
+ .map((i, el) => $(el).text().trim())
+ .get();
+
+ res.topAiringAnimes.push({
+ id: $(el)
+ .find(".film-detail .film-name .dynamic-name")
+ ?.attr("href")
+ ?.slice(1)
+ ?.trim(),
+ name: $(el)
+ .find(".film-detail .film-name .dynamic-name")
+ ?.attr("title")
+ ?.trim(),
+ jname: $(el)
+ .find(".film-detail .film-name .dynamic-name")
+ ?.attr("data-jname")
+ ?.trim(),
+ poster: $(el)
+ .find(".film-poster a .film-poster-img")
+ ?.attr("data-src")
+ ?.trim(),
+ otherInfo,
+ });
+ });
+
+ return res;
+ } catch (err: any) {
+ if (err instanceof AxiosError) {
+ throw createHttpError(
+ err?.response?.status || 500,
+ err?.response?.statusText || "Something went wrong"
+ );
+ }
+ throw createHttpError.InternalServerError(err?.message);
+ }
+}
+
+export default scrapeHomePage;