diff options
| author | Ritesh Ghosh <[email protected]> | 2023-08-03 23:57:55 +0530 |
|---|---|---|
| committer | Ritesh Ghosh <[email protected]> | 2023-08-03 23:57:55 +0530 |
| commit | 65f863b3c11c98b9f34bfdc57ba8e896110dcf22 (patch) | |
| tree | b298826b3288166e86b32f33f3b3ed94f4389f6f /src | |
| parent | 8f1eabe2d9162ade3adcd604417f4f2b8ce95265 (diff) | |
| download | aniwatch-api-65f863b3c11c98b9f34bfdc57ba8e896110dcf22.tar.xz aniwatch-api-65f863b3c11c98b9f34bfdc57ba8e896110dcf22.zip | |
feat(newParser): added `animeGenre` parser
Diffstat (limited to 'src')
| -rw-r--r-- | src/parsers/animeGenre.ts | 111 |
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; |
