File size: 3,388 Bytes
11acfd9 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
import {
SRC_BASE_URL,
ACCEPT_HEADER,
USER_AGENT_HEADER,
ACCEPT_ENCODING_HEADER,
extractMostPopularAnimes,
extractAnimes,
extractTop10Animes,
} from "../utils/index.js";
import axios, { AxiosError } from "axios";
import createHttpError, { type HttpError } from "http-errors";
import { load, type CheerioAPI, type SelectorType } from "cheerio";
import type { ScrapedProducerAnime } from "../types/parsers/index.js";
// /anime/producer/${name}?page=${page}
async function scrapeProducerAnimes(
producerName: string,
page: number = 1
): Promise<ScrapedProducerAnime | HttpError> {
const res: ScrapedProducerAnime = {
producerName,
animes: [],
top10Animes: {
today: [],
week: [],
month: [],
},
topAiringAnimes: [],
totalPages: 1,
hasNextPage: false,
currentPage: Number(page),
};
try {
const producerUrl: URL = new URL(
`/producer/${producerName}?page=${page}`,
SRC_BASE_URL
);
const mainPage = await axios.get(producerUrl.href, {
headers: {
Accept: ACCEPT_HEADER,
"User-Agent": USER_AGENT_HEADER,
"Accept-Encoding": ACCEPT_ENCODING_HEADER,
},
});
const $: CheerioAPI = load(mainPage.data);
const animeSelector: 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 =
Number(
$('.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()
) || 1;
res.animes = extractAnimes($, animeSelector);
if (res.animes.length === 0 && !res.hasNextPage) {
res.totalPages = 0;
}
const producerNameSelector: SelectorType =
"#main-content .block_area .block_area-header .cat-heading";
res.producerName = $(producerNameSelector)?.text()?.trim() ?? producerName;
const top10AnimeSelector: SelectorType =
'#main-sidebar .block_area-realtime [id^="top-viewed-"]';
$(top10AnimeSelector).each((_, 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 =
"#main-sidebar .block_area_sidebar:nth-child(2) .block_area-content .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 scrapeProducerAnimes;
|