File size: 2,265 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
import {
  SRC_HOME_URL,
  SRC_AJAX_URL,
  USER_AGENT_HEADER,
  ACCEPT_ENCODING_HEADER,
} 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 { ScrapedAnimeSearchSuggestion } from "../types/parsers/index.js";

// /anime/search/suggest?q=${query}
async function scrapeAnimeSearchSuggestion(
  q: string
): Promise<ScrapedAnimeSearchSuggestion | HttpError> {
  const res: ScrapedAnimeSearchSuggestion = {
    suggestions: [],
  };

  try {
    const { data } = await axios.get(
      `${SRC_AJAX_URL}/search/suggest?keyword=${encodeURIComponent(q)}`,
      {
        headers: {
          Accept: "*/*",
          Pragma: "no-cache",
          Referer: SRC_HOME_URL,
          "User-Agent": USER_AGENT_HEADER,
          "X-Requested-With": "XMLHttpRequest",
          "Accept-Encoding": ACCEPT_ENCODING_HEADER,
        },
      }
    );

    const $: CheerioAPI = load(data.html);
    const selector: SelectorType = ".nav-item:has(.film-poster)";

    if ($(selector).length < 1) return res;

    $(selector).each((_, el) => {
      const id = $(el).attr("href")?.split("?")[0].includes("javascript")
        ? null
        : $(el).attr("href")?.split("?")[0]?.slice(1);

      res.suggestions.push({
        id,
        name: $(el).find(".srp-detail .film-name")?.text()?.trim() || null,
        jname:
          $(el).find(".srp-detail .film-name")?.attr("data-jname")?.trim() ||
          $(el).find(".srp-detail .alias-name")?.text()?.trim() ||
          null,
        poster: $(el)
          .find(".film-poster .film-poster-img")
          ?.attr("data-src")
          ?.trim(),
        moreInfo: [
          ...$(el)
            .find(".film-infor")
            .contents()
            .map((_, el) => $(el).text().trim()),
        ].filter((i) => i),
      });
    });

    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 scrapeAnimeSearchSuggestion;