mirror of
https://github.com/movie-web/providers.git
synced 2025-09-13 15:43:26 +00:00
Add kissasian scraper
This commit is contained in:
@@ -3,11 +3,12 @@ import { mp4uploadScraper } from '@/providers/embeds/mp4upload';
|
||||
import { streamsbScraper } from '@/providers/embeds/streamsb';
|
||||
import { upcloudScraper } from '@/providers/embeds/upcloud';
|
||||
import { flixhqScraper } from '@/providers/sources/flixhq/index';
|
||||
import { kissAsianScraper } from '@/providers/sources/kissasian/index';
|
||||
import { remotestreamScraper } from '@/providers/sources/remotestream';
|
||||
|
||||
export function gatherAllSources(): Array<Sourcerer> {
|
||||
// all sources are gathered here
|
||||
return [flixhqScraper, remotestreamScraper];
|
||||
return [flixhqScraper, remotestreamScraper, kissAsianScraper];
|
||||
}
|
||||
|
||||
export function gatherAllEmbeds(): Array<Embed> {
|
||||
|
15
src/providers/sources/kissasian/common.ts
Normal file
15
src/providers/sources/kissasian/common.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { mp4uploadScraper } from '@/providers/embeds/mp4upload';
|
||||
import { streamsbScraper } from '@/providers/embeds/streamsb';
|
||||
|
||||
export const kissasianBase = 'https://kissasian.li';
|
||||
|
||||
export const embedProviders = [
|
||||
{
|
||||
type: mp4uploadScraper.id,
|
||||
id: 'mp',
|
||||
},
|
||||
{
|
||||
type: streamsbScraper.id,
|
||||
id: 'sb',
|
||||
},
|
||||
];
|
34
src/providers/sources/kissasian/getEmbeds.ts
Normal file
34
src/providers/sources/kissasian/getEmbeds.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { load } from 'cheerio';
|
||||
|
||||
import { ScrapeContext } from '@/utils/context';
|
||||
|
||||
import { embedProviders, kissasianBase } from './common';
|
||||
|
||||
export async function getEmbeds(
|
||||
ctx: ScrapeContext,
|
||||
targetEpisode: {
|
||||
number: string;
|
||||
url?: string;
|
||||
},
|
||||
) {
|
||||
let embeds = await Promise.all(
|
||||
embedProviders.map(async (provider) => {
|
||||
const watch = await ctx.fetcher<any>(`${kissasianBase}/${targetEpisode.url}&s=${provider.id}`);
|
||||
|
||||
const watchPage = load(watch);
|
||||
|
||||
const embedUrl = watchPage('iframe[id=my_video_1]').attr('src');
|
||||
|
||||
if (!embedUrl) throw new Error('Embed not found');
|
||||
|
||||
return {
|
||||
embedId: provider.id,
|
||||
url: embedUrl,
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
embeds = embeds.filter((e) => !!e.url);
|
||||
|
||||
return embeds;
|
||||
}
|
14
src/providers/sources/kissasian/getEpisodes.ts
Normal file
14
src/providers/sources/kissasian/getEpisodes.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { CheerioAPI } from 'cheerio';
|
||||
|
||||
export async function getEpisodes(dramaPage: CheerioAPI) {
|
||||
const episodesEl = dramaPage('tbody tr:not(:first-child)');
|
||||
|
||||
return episodesEl
|
||||
.toArray()
|
||||
.map((ep) => {
|
||||
const number = dramaPage(ep).find('td.episodeSub a').text().split('Episode')[1]?.trim();
|
||||
const url = dramaPage(ep).find('td.episodeSub a').attr('href');
|
||||
return { number, url };
|
||||
})
|
||||
.filter((e) => !!e.url);
|
||||
}
|
70
src/providers/sources/kissasian/index.ts
Normal file
70
src/providers/sources/kissasian/index.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { load } from 'cheerio';
|
||||
|
||||
import { flags } from '@/main/targets';
|
||||
import { makeSourcerer } from '@/providers/base';
|
||||
import { NotFoundError } from '@/utils/errors';
|
||||
|
||||
import { getEmbeds } from './getEmbeds';
|
||||
import { getEpisodes } from './getEpisodes';
|
||||
import { search } from './search';
|
||||
|
||||
export const kissAsianScraper = makeSourcerer({
|
||||
id: 'kissasian',
|
||||
name: 'KissAsian',
|
||||
rank: 130,
|
||||
flags: [flags.NO_CORS],
|
||||
|
||||
async scrapeShow(ctx) {
|
||||
const seasonNumber = ctx.media.season.number;
|
||||
const episodeNumber = ctx.media.episode.number;
|
||||
|
||||
const dramas = await search(ctx, ctx.media.title, seasonNumber);
|
||||
|
||||
const targetDrama = dramas.find((d) => d.name?.toLowerCase() === ctx.media.title.toLowerCase()) ?? dramas[0];
|
||||
if (!targetDrama) throw new Error('Drama not found');
|
||||
|
||||
ctx.progress(30);
|
||||
|
||||
const drama = await ctx.fetcher<any>(targetDrama.url);
|
||||
|
||||
const dramaPage = load(drama);
|
||||
|
||||
const episodes = await getEpisodes(dramaPage);
|
||||
|
||||
const targetEpisode = episodes.find((e) => e.number === `${episodeNumber}`);
|
||||
if (!targetEpisode?.url) throw new NotFoundError('Episode not found');
|
||||
|
||||
ctx.progress(70);
|
||||
|
||||
const embeds = await getEmbeds(ctx, targetEpisode);
|
||||
|
||||
return {
|
||||
embeds,
|
||||
};
|
||||
},
|
||||
async scrapeMovie(ctx) {
|
||||
const dramas = await search(ctx, ctx.media.title, undefined);
|
||||
|
||||
const targetDrama = dramas.find((d) => d.name?.toLowerCase() === ctx.media.title.toLowerCase()) ?? dramas[0];
|
||||
if (!targetDrama) throw new Error('Drama not found');
|
||||
|
||||
ctx.progress(30);
|
||||
|
||||
const drama = await ctx.fetcher<any>(targetDrama.url);
|
||||
|
||||
const dramaPage = load(drama);
|
||||
|
||||
const episodes = await getEpisodes(dramaPage);
|
||||
|
||||
const targetEpisode = episodes[0];
|
||||
if (!targetEpisode?.url) throw new NotFoundError('Episode not found');
|
||||
|
||||
ctx.progress(70);
|
||||
|
||||
const embeds = await getEmbeds(ctx, targetEpisode);
|
||||
|
||||
return {
|
||||
embeds,
|
||||
};
|
||||
},
|
||||
});
|
27
src/providers/sources/kissasian/search.ts
Normal file
27
src/providers/sources/kissasian/search.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { load } from 'cheerio';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import { ScrapeContext } from '@/utils/context';
|
||||
|
||||
import { kissasianBase } from './common';
|
||||
|
||||
export async function search(ctx: ScrapeContext, title: string, seasonNumber?: number) {
|
||||
const searchForm = new FormData();
|
||||
searchForm.append('keyword', `${title} ${seasonNumber ?? ''}`.trim());
|
||||
searchForm.append('type', 'Drama');
|
||||
|
||||
const searchResults = await ctx.fetcher<any>('/Search/SearchSuggest', {
|
||||
baseUrl: kissasianBase,
|
||||
method: 'POST',
|
||||
body: searchForm,
|
||||
});
|
||||
|
||||
const searchPage = load(searchResults);
|
||||
|
||||
return Array.from(searchPage('a')).map((drama) => {
|
||||
return {
|
||||
name: searchPage(drama).text(),
|
||||
url: drama.attribs.href,
|
||||
};
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user