better-ani-scraped 1.1.1 → 1.2.1
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.
- package/examples/example_usage_01.js +2 -2
- package/package.json +1 -1
- package/scrapers/animesama.js +72 -42
|
@@ -3,7 +3,7 @@ import { AnimeScraper, getVideoUrlFromEmbed } from "../index.js"; // REPLACE BY
|
|
|
3
3
|
const main = async () => {
|
|
4
4
|
const scraper = new AnimeScraper('animesama');
|
|
5
5
|
|
|
6
|
-
const search = await scraper.searchAnime("
|
|
6
|
+
const search = await scraper.searchAnime("86");
|
|
7
7
|
console.log("Search Results:", search);
|
|
8
8
|
|
|
9
9
|
const animeUrl = Object.values(search)[0].url;
|
|
@@ -16,7 +16,7 @@ const main = async () => {
|
|
|
16
16
|
]);
|
|
17
17
|
console.log("Embed Links:", embeds);
|
|
18
18
|
|
|
19
|
-
const videoUrl = await getVideoUrlFromEmbed("sibnet", embeds[
|
|
19
|
+
const videoUrl = await getVideoUrlFromEmbed("sibnet", embeds[0].url)
|
|
20
20
|
console.log("Video URL:", videoUrl);
|
|
21
21
|
};
|
|
22
22
|
|
package/package.json
CHANGED
package/scrapers/animesama.js
CHANGED
|
@@ -125,37 +125,56 @@ export async function getSeasons(animeUrl, language = "vostfr") {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
export async function getEpisodeTitles(animeUrl) {
|
|
128
|
-
|
|
128
|
+
const puppeteer = await import('puppeteer');
|
|
129
|
+
let browser;
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
browser = await puppeteer.launch({
|
|
133
|
+
headless: true,
|
|
134
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const page = await browser.newPage();
|
|
138
|
+
|
|
139
|
+
await page.setUserAgent(
|
|
140
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
await page.setRequestInterception(true);
|
|
144
|
+
page.on('request', (req) => {
|
|
145
|
+
const blocked = ['image', 'stylesheet', 'font', 'media'];
|
|
146
|
+
if (blocked.includes(req.resourceType())) req.abort();
|
|
147
|
+
else req.continue();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
console.log("▶️ Navigation vers", animeUrl);
|
|
151
|
+
await page.goto(animeUrl, { waitUntil: 'domcontentloaded', timeout: 20000 });
|
|
152
|
+
|
|
129
153
|
try {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const blocked = ['image', 'stylesheet', 'font', 'media'];
|
|
138
|
-
if (blocked.includes(req.resourceType())) {
|
|
139
|
-
req.abort();
|
|
140
|
-
} else {
|
|
141
|
-
req.continue();
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
await page.goto(animeUrl, { waitUntil: 'domcontentloaded' });
|
|
145
|
-
await page.waitForSelector('#selectEpisodes');
|
|
146
|
-
// Récupération des titres d'épisodes
|
|
147
|
-
const titres = await page.$$eval('#selectEpisodes option', options =>
|
|
148
|
-
options.map(o => o.textContent.trim())
|
|
149
|
-
);
|
|
150
|
-
return titres;
|
|
151
|
-
} catch (error) {
|
|
152
|
-
console.error('Erreur dans la récupération des titres:', error);
|
|
153
|
-
return [];
|
|
154
|
-
} finally {
|
|
155
|
-
if (browser) await browser.close();
|
|
154
|
+
await page.waitForSelector('#selectEpisodes', { timeout: 7000 });
|
|
155
|
+
} catch (waitError) {
|
|
156
|
+
console.warn("⚠️ Sélecteur #selectEpisodes introuvable :", waitError.message);
|
|
157
|
+
|
|
158
|
+
const htmlDump = await page.content();
|
|
159
|
+
require("fs").writeFileSync("debug_selectEpisodes.html", htmlDump);
|
|
160
|
+
return [];
|
|
156
161
|
}
|
|
162
|
+
|
|
163
|
+
const titres = await page.$$eval('#selectEpisodes option', options =>
|
|
164
|
+
options.map(o => o.textContent.trim())
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
console.log(`✅ ${titres.length} titres récupérés`);
|
|
168
|
+
return titres;
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error('❌ Erreur dans getEpisodeTitles:', error.message);
|
|
171
|
+
return [];
|
|
172
|
+
} finally {
|
|
173
|
+
if (browser) await browser.close();
|
|
174
|
+
}
|
|
157
175
|
}
|
|
158
176
|
|
|
177
|
+
|
|
159
178
|
export async function getEmbed(animeUrl, hostPriority = ["vidmoly"]) {
|
|
160
179
|
const res = await axios.get(animeUrl, {
|
|
161
180
|
headers: getHeaders(animeUrl.split("/").slice(0, 5).join("/")),
|
|
@@ -178,34 +197,45 @@ export async function getEmbed(animeUrl, hostPriority = ["vidmoly"]) {
|
|
|
178
197
|
];
|
|
179
198
|
if (!matches.length) throw new Error("No episode arrays found");
|
|
180
199
|
|
|
181
|
-
|
|
182
|
-
|
|
200
|
+
// Parse les arrays et crée une matrice [epsX][index]
|
|
201
|
+
let episodeMatrix = [];
|
|
183
202
|
for (const [, , arrayString] of matches) {
|
|
184
203
|
try {
|
|
185
|
-
const links = eval(arrayString);
|
|
186
|
-
|
|
204
|
+
const links = eval(arrayString);
|
|
205
|
+
episodeMatrix.push(links);
|
|
187
206
|
} catch (e) {
|
|
188
207
|
console.warn("Could not parse embed array:", e);
|
|
189
208
|
}
|
|
190
209
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
210
|
+
|
|
211
|
+
// Déterminer le nombre total d'épisodes max (plus long des arrays)
|
|
212
|
+
const maxEpisodes = Math.max(...episodeMatrix.map(arr => arr.length));
|
|
213
|
+
const finalEmbeds = [];
|
|
214
|
+
|
|
215
|
+
// Parcours vertical
|
|
216
|
+
for (let i = 0; i < maxEpisodes; i++) {
|
|
217
|
+
let selectedUrl = null;
|
|
218
|
+
|
|
219
|
+
for (const host of hostPriority) {
|
|
220
|
+
for (const arr of episodeMatrix) {
|
|
221
|
+
if (i < arr.length && arr[i].includes(host)) {
|
|
222
|
+
selectedUrl = arr[i];
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (selectedUrl) break;
|
|
199
227
|
}
|
|
228
|
+
|
|
229
|
+
finalEmbeds.push(selectedUrl || null);
|
|
200
230
|
}
|
|
231
|
+
|
|
201
232
|
const titles = await getEpisodeTitles(animeUrl);
|
|
202
|
-
return titles.slice(0,
|
|
233
|
+
return titles.slice(0, finalEmbeds.length).map((title, i) => ({
|
|
203
234
|
title,
|
|
204
|
-
url:
|
|
235
|
+
url: finalEmbeds[i]
|
|
205
236
|
}));
|
|
206
237
|
}
|
|
207
238
|
|
|
208
|
-
|
|
209
239
|
export async function getAnimeInfo(animeUrl) {
|
|
210
240
|
const res = await axios.get(animeUrl, { headers: getHeaders(CATALOGUE_URL) });
|
|
211
241
|
const $ = cheerio.load(res.data);
|