better-ani-scraped 1.6.6 → 1.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { AnimeScraper } from "../../index.js"; // REPLACE BY "from 'better-ani-s
3
3
  const main = async () => {
4
4
  const animesama = new AnimeScraper('animesama');
5
5
 
6
- const search = await animesama.searchAnime("a", 100, ["vostfr", "vf", "vastfr"], ["Anime", "Film"], 2);
6
+ const search = await animesama.searchAnime("gachiakuta", 100, [], ["Anime", "Film", "Autres", "Scans"]);
7
7
  console.log("Search Results:", search);
8
8
  };
9
9
 
@@ -3,8 +3,10 @@ import { getVideoUrlFromEmbed } from "../../index.js"; // REPLACE BY "from 'bett
3
3
  const main = async () => {
4
4
  const embedUrlSibnet = "https://video.sibnet.ru/shell.php?videoid=4291083";
5
5
  const embedUrlSendvid = "https://sendvid.com/embed/4vzpcb0q";
6
- const embedUrlVidmoly = "https://vidmoly.to/embed-vt374ef2joph.html";
6
+ const embedUrlVidmoly = "https://vidmoly.to/embed-rvqrwg5zk37w.html";
7
7
  const embedUrlOneupload = "https://oneupload.net/embed-axdrxh1y3p37.html";
8
+ const embedUrlSmoothpre = "https://smoothpre.com/embed/8294jcf1q8jf";
9
+ const embedUrlMovearnpre = "https://movearnpre.com/embed/e3xbkin87yt3";
8
10
 
9
11
  const videoUrlSibnet = await getVideoUrlFromEmbed("sibnet", embedUrlSibnet)
10
12
  console.log("Video URL Sibnet:", videoUrlSibnet);
@@ -17,6 +19,13 @@ const main = async () => {
17
19
 
18
20
  const videoUrlOneupload = await getVideoUrlFromEmbed("oneupload", embedUrlOneupload)
19
21
  console.log("Video URL Oneupload:", videoUrlOneupload);
22
+
23
+ const videoUrlSmoothpre = await getVideoUrlFromEmbed("smoothpre", embedUrlSmoothpre)
24
+ console.log("Video URL Smoothpre:", videoUrlSmoothpre);
25
+
26
+ const videoUrlMovearnpre = await getVideoUrlFromEmbed("movearnpre", embedUrlMovearnpre)
27
+ console.log("Video URL Movearnpre:", videoUrlMovearnpre);
28
+
20
29
  };
21
30
 
22
31
  main().catch(console.error);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "better-ani-scraped",
3
- "version": "1.6.6",
4
- "description": "Scrape anime data from different sources (only anime-sama.fr for the moment)",
3
+ "version": "1.6.9",
4
+ "description": "Scrape anime data from different sources (only anime-sama.fr, animepahe and crunchyroll for the moment)",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -46,12 +46,15 @@ function getHeaders(referer = BASE_URL) {
46
46
  export async function searchAnime(
47
47
  query,
48
48
  limit = 10,
49
- wantedLanguages = ["vostfr", "vf", "vastfr"],
50
- wantedTypes = ["Anime", "Film"],
49
+ wantedLanguages = null,
50
+ wantedTypes = null,
51
51
  page = null
52
52
  ) {
53
+ const languages = Array.isArray(wantedLanguages) ? wantedLanguages : ["vostfr", "vf", "vastfr"];
54
+ const types = Array.isArray(wantedTypes) ? wantedTypes : ["Anime", "Film"];
55
+
53
56
  const isWanted = (text, list) =>
54
- list.some(item => text.toLowerCase().includes(item.toLowerCase()));
57
+ list.length === 0 || list.some(item => text.toLowerCase().includes(item.toLowerCase()));
55
58
 
56
59
  const results = [];
57
60
 
@@ -76,11 +79,11 @@ export async function searchAnime(
76
79
  const cover = anchor.find("img").first().attr("src");
77
80
 
78
81
  const tagText = anchor.find("p").filter((_, p) =>
79
- isWanted($(p).text(), wantedTypes)
82
+ isWanted($(p).text(), types)
80
83
  ).first().text();
81
84
 
82
85
  const languageText = anchor.find("p").filter((_, p) =>
83
- isWanted($(p).text(), wantedLanguages)
86
+ isWanted($(p).text(), languages)
84
87
  ).first().text();
85
88
 
86
89
  const altTitles = altRaw
@@ -92,7 +95,10 @@ export async function searchAnime(
92
95
  ? genreRaw.split(",").map((g) => g.trim()).filter(Boolean)
93
96
  : [];
94
97
 
95
- if (title && link && tagText && languageText) {
98
+ const hasValidType = types.length === 0 || tagText;
99
+ const hasValidLanguage = languages.length === 0 || languageText;
100
+
101
+ if (title && link && hasValidType && hasValidLanguage) {
96
102
  results.push({
97
103
  title,
98
104
  altTitles,
@@ -181,11 +187,15 @@ export async function getEpisodeTitles(seasonUrl, customChromiumPath) {
181
187
  browser = await puppeteer.launch({
182
188
  headless: true,
183
189
  executablePath,
184
- args: ['--no-sandbox', '--disable-setuid-sandbox'],
190
+ args: [
191
+ '--no-sandbox',
192
+ '--disable-setuid-sandbox',
193
+ ]
194
+
185
195
  });
186
196
 
187
197
  const page = await browser.newPage();
188
-
198
+ await page.setExtraHTTPHeaders(getHeaders(seasonUrl));
189
199
  await page.setRequestInterception(true);
190
200
  page.on('request', (req) => {
191
201
  const blocked = ['image', 'stylesheet', 'font', 'media'];
@@ -195,9 +205,13 @@ export async function getEpisodeTitles(seasonUrl, customChromiumPath) {
195
205
  req.continue();
196
206
  }
197
207
  });
198
-
208
+ await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ' + '(KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36');
209
+ await page.evaluateOnNewDocument(() => {
210
+ Object.defineProperty(navigator, 'webdriver', { get: () => false });
211
+ });
199
212
  await page.goto(seasonUrl, { waitUntil: 'domcontentloaded' });
200
213
  await page.waitForSelector('#selectEpisodes');
214
+
201
215
 
202
216
  const titres = await page.$$eval('#selectEpisodes option', options =>
203
217
  options.map(o => o.textContent.trim())
@@ -595,4 +609,3 @@ export async function getRandomAnime(
595
609
  return null;
596
610
  }
597
611
  }
598
-
@@ -10,6 +10,9 @@ export async function getVideoUrlFromEmbed(source, embedUrl) {
10
10
  if (source === "vidmoly" || source === "oneupload" ) {
11
11
  return await extractor.getVidmolyOrOneuploadVideo(embedUrl);
12
12
  }
13
+ if (source === "movearnpre" || source === "smoothpre" ) {
14
+ return await extractor.getMovearnpreOrSmoothpreVideo(embedUrl);
15
+ }
13
16
 
14
17
  throw new Error(`Unsupported embed source: ${source}`);
15
18
  }
@@ -53,11 +53,13 @@ export async function getSendvidVideo(embedUrl) {
53
53
 
54
54
  export async function getVidmolyOrOneuploadVideo(embedUrl) {
55
55
  try {
56
+ if (embedUrl.includes("vidmoly.to/")) {
57
+ embedUrl = embedUrl.replace("vidmoly.to/", "vidmoly.net/");
58
+ }
56
59
  console.log(embedUrl)
57
60
  const { data } = await axios.get(embedUrl, {
58
61
  headers: getHeaders(embedUrl),
59
62
  });
60
- console.log(data)
61
63
  const $ = cheerio.load(data);
62
64
  const scripts = $("script");
63
65
 
@@ -74,3 +76,28 @@ export async function getVidmolyOrOneuploadVideo(embedUrl) {
74
76
  return null;
75
77
  }
76
78
  }
79
+
80
+ import puppeteer from 'puppeteer';
81
+
82
+ export async function getMovearnpreOrSmoothpreVideo(embedUrl) {
83
+ const browser = await puppeteer.launch({ headless: true });
84
+ const page = await browser.newPage();
85
+
86
+ await page.setUserAgent(
87
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"
88
+ );
89
+
90
+ await page.goto(embedUrl, { waitUntil: 'networkidle2' });
91
+
92
+ await page.waitForFunction('typeof jwplayer !== "undefined"');
93
+
94
+ const videoUrl = await page.evaluate(() => {
95
+ const player = jwplayer();
96
+ const sources = player?.getPlaylist()?.[0]?.sources;
97
+ return sources?.[0]?.file || null;
98
+ });
99
+
100
+ await browser.close();
101
+ const finalUrl = embedUrl.split("/").slice(0, 3).join("/") + videoUrl
102
+ return finalUrl;
103
+ }