aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRitesh Ghosh <[email protected]>2023-08-02 13:44:57 +0530
committerRitesh Ghosh <[email protected]>2023-08-02 13:44:57 +0530
commita3a74145c4ac949646d3dd8ce4248aaa10ffb257 (patch)
tree7b5e114e3acd80f924dab55ea60605abd6430a5d /src
parentb1357dea6eb1d1f845ec793d3954281e622da734 (diff)
downloadaniwatch-api-a3a74145c4ac949646d3dd8ce4248aaa10ffb257.tar.xz
aniwatch-api-a3a74145c4ac949646d3dd8ce4248aaa10ffb257.zip
feat: added anime category parser
Diffstat (limited to 'src')
-rw-r--r--src/parsers/animeCategory.ts119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/parsers/animeCategory.ts b/src/parsers/animeCategory.ts
new file mode 100644
index 0000000..6b88a08
--- /dev/null
+++ b/src/parsers/animeCategory.ts
@@ -0,0 +1,119 @@
+import axios, { AxiosError } from "axios";
+import { load, CheerioAPI, SelectorType } from "cheerio";
+import {
+ SRC_BASE_URL,
+ ACCEPT_HEADER,
+ USER_AGENT_HEADER,
+ ACCEPT_ENCODING_HEADER,
+ extractAnimes,
+ extractTop10Animes,
+} from "../utils";
+
+import createHttpError, { HttpError, isHttpError } from "http-errors";
+import { ScrapedAnimeCategory, AnimeCategories } from "../models";
+
+// /anime/:category?page=${page}
+async function scrapeAnimeCategory(
+ category: AnimeCategories,
+ page: number = 1
+): Promise<ScrapedAnimeCategory | HttpError> {
+ const res: ScrapedAnimeCategory = {
+ animes: [],
+ genres: [],
+ top10Animes: {
+ today: [],
+ week: [],
+ month: [],
+ },
+ category,
+ currentPage: Number(page),
+ hasNextPage: false,
+ totalPages: 0,
+ };
+
+ try {
+ const scrapeUrl: URL = new URL(category, SRC_BASE_URL);
+ const mainPage = await axios.get(`${scrapeUrl}?page=${page}`, {
+ headers: {
+ "User-Agent": USER_AGENT_HEADER,
+ "Accept-Encoding": ACCEPT_ENCODING_HEADER,
+ Accept: ACCEPT_HEADER,
+ },
+ });
+
+ const $: CheerioAPI = load(mainPage.data);
+
+ const selector: SelectorType =
+ "#main-content .tab-content .film_list-wrap .flw-item";
+
+ res.hasNextPage =
+ $(".pagination > li").length > 0
+ ? $(".pagination li.active").length > 0
+ ? $(".pagination > li").last().hasClass("active")
+ ? false
+ : true
+ : false
+ : false;
+
+ res.totalPages =
+ parseInt(
+ $('.pagination > .page-item a[title="Last"]')
+ ?.attr("href")
+ ?.split("=")
+ .pop() ??
+ $('.pagination > .page-item a[title="Next"]')
+ ?.attr("href")
+ ?.split("=")
+ .pop() ??
+ $(".pagination > .page-item.active a")?.text()?.trim()
+ ) || 0;
+
+ if (res.totalPages === 0 && !res.hasNextPage) {
+ res.totalPages = 0;
+ }
+
+ res.animes = extractAnimes($, selector);
+
+ if (res.animes.length === 0) {
+ res.totalPages = 0;
+ res.hasNextPage = false;
+ }
+
+ 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 top10AnimeSelector: SelectorType =
+ '#main-sidebar .block_area-realtime [id^="top-viewed-"]';
+
+ $(top10AnimeSelector).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);
+ }
+ });
+
+ 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 scrapeAnimeCategory;