aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRitesh Ghosh <[email protected]>2023-08-03 23:57:55 +0530
committerRitesh Ghosh <[email protected]>2023-08-03 23:57:55 +0530
commit65f863b3c11c98b9f34bfdc57ba8e896110dcf22 (patch)
treeb298826b3288166e86b32f33f3b3ed94f4389f6f /src
parent8f1eabe2d9162ade3adcd604417f4f2b8ce95265 (diff)
downloadaniwatch-api-65f863b3c11c98b9f34bfdc57ba8e896110dcf22.tar.xz
aniwatch-api-65f863b3c11c98b9f34bfdc57ba8e896110dcf22.zip
feat(newParser): added `animeGenre` parser
Diffstat (limited to 'src')
-rw-r--r--src/parsers/animeGenre.ts111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/parsers/animeGenre.ts b/src/parsers/animeGenre.ts
new file mode 100644
index 0000000..a3c1b5a
--- /dev/null
+++ b/src/parsers/animeGenre.ts
@@ -0,0 +1,111 @@
+import axios, { AxiosError } from "axios";
+import { load, CheerioAPI, SelectorType } from "cheerio";
+import {
+ SRC_BASE_URL,
+ ACCEPT_HEADER,
+ USER_AGENT_HEADER,
+ ACCEPT_ENCODING_HEADER,
+ extractMostPopularAnimes,
+ extractAnimes,
+} from "../utils";
+
+import createHttpError, { HttpError } from "http-errors";
+import { ScrapedGenreAnime } from "../models";
+
+// /anime/genre?name=${genreName}&page=${page}
+async function scrapeGenreAnime(
+ genreName: string,
+ page: number = 1
+): Promise<ScrapedGenreAnime | HttpError> {
+ const res: ScrapedGenreAnime = {
+ genreName,
+ animes: [],
+ genres: [],
+ topAiringAnimes: [],
+ totalPages: 0,
+ hasNextPage: false,
+ currentPage: Number(page),
+ };
+
+ // there's a typo with zoro where martial arts is marial arts
+ genreName = genreName === "martial-arts" ? "marial-arts" : genreName;
+
+ try {
+ const genreUrl: URL = new URL(
+ `/genre/${genreName}?page=${page}`,
+ SRC_BASE_URL
+ );
+
+ const mainPage = await axios.get(genreUrl.href, {
+ 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";
+
+ const genreNameSelector: SelectorType =
+ "#main-content .block_area .block_area-header .cat-heading";
+ res.genreName = $(genreNameSelector)?.text()?.trim() ?? genreName;
+
+ 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 topAiringSelector: SelectorType =
+ "#main-sidebar .block_area.block_area_sidebar.block_area-realtime .anif-block-ul ul li";
+ res.topAiringAnimes = extractMostPopularAnimes($, topAiringSelector);
+
+ 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 scrapeGenreAnime;