feat(scraper): add each scraper and its parser flow
このコミットが含まれているのは:
コミット
759c79c266
|
@ -0,0 +1,78 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { IVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const resolve = await lust.fetchBody(url);
|
||||
const $ = load(resolve);
|
||||
|
||||
class PornHub {
|
||||
link: string;
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
duration: string;
|
||||
views: string;
|
||||
rating: string;
|
||||
videoInfo: string;
|
||||
upVote: string;
|
||||
downVote: string;
|
||||
video: string;
|
||||
tags: string[];
|
||||
models: string[];
|
||||
constructor() {
|
||||
this.link = $("link[rel='canonical']").attr("href") || "None";
|
||||
this.id = this.link.split("=")[1] || "None";
|
||||
this.title = $("meta[property='og:title']").attr("content") || "None";
|
||||
this.image = $("meta[property='og:image']").attr("content") || "None";
|
||||
//get <meta property="video:duration" content="
|
||||
this.duration = $("meta[property='video:duration']").attr("content") || "0";
|
||||
this.views = $("div.views > span.count").text() || "None";
|
||||
this.rating = $("div.ratingPercent > span.percent").text() || "None";
|
||||
this.videoInfo = $("div.videoInfo").text() || "None";
|
||||
this.upVote = $("span.votesUp").attr("data-rating") || "None";
|
||||
this.downVote = $("span.votesDown").attr("data-rating") || "None";
|
||||
this.video = $("meta[property='og:video:url']").attr("content") || "None";
|
||||
this.tags = $("div.video-info-row")
|
||||
.find("a")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.tags.shift();
|
||||
this.tags = this.tags.map((el) => lust.removeHtmlTagWithoutSpace(el));
|
||||
this.models = $("div.pornstarsWrapper.js-pornstarsWrapper")
|
||||
.find("a")
|
||||
.map((i, el) => {
|
||||
return $(el).attr("data-mxptext");
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const ph = new PornHub();
|
||||
const data: IVideoData = {
|
||||
success: true,
|
||||
data: {
|
||||
title: lust.removeHtmlTagWithoutSpace(ph.title),
|
||||
id: ph.id,
|
||||
image: ph.image,
|
||||
duration: lust.secondToMinute(Number(ph.duration)),
|
||||
views: ph.views,
|
||||
rating: ph.rating,
|
||||
uploaded: ph.videoInfo,
|
||||
upvoted: ph.upVote,
|
||||
downvoted: ph.downVote,
|
||||
models: ph.models,
|
||||
tags: ph.tags.filter((el) => el !== "Suggest" && el !== " Suggest")
|
||||
},
|
||||
source: ph.link,
|
||||
assets: [ph.video, ph.image]
|
||||
};
|
||||
return data;
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class PornhubSearch {
|
||||
search: object[];
|
||||
data: object;
|
||||
constructor() {
|
||||
this.search = $("div.wrap")
|
||||
.map((i, el) => {
|
||||
const link = $(el).find("a").attr("href");
|
||||
const id = link?.split("=")[1];
|
||||
const title = $(el).find("a").attr("title");
|
||||
const image = $(el).find("img").attr("src");
|
||||
const duration = $(el).find("var.duration").text();
|
||||
const views = $(el).find("div.videoDetailsBlock").find("span.views").text();
|
||||
return {
|
||||
link: `${c.PORNHUB}${link}`,
|
||||
id: id,
|
||||
title: title,
|
||||
image: image,
|
||||
duration: duration,
|
||||
views: views,
|
||||
video: `${c.PORNHUB}/embed/${id}`,
|
||||
};
|
||||
}).get();
|
||||
|
||||
this.data = this.search.filter((el: any) => {
|
||||
return el.link.includes("javascript:void(0)") === false && el.image?.startsWith("data:image") === false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const ph = new PornhubSearch();
|
||||
if (ph.search.length === 0) throw Error("No result found");
|
||||
const data = ph.data as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { IVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const resolve = await lust.fetchBody(url);
|
||||
const $ = load(resolve);
|
||||
|
||||
class RedTube {
|
||||
link: string;
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
duration: string;
|
||||
views: string;
|
||||
rating: string;
|
||||
publish: string;
|
||||
upVote: string;
|
||||
downVote: null;
|
||||
video: string;
|
||||
tags: string[];
|
||||
models: string[];
|
||||
constructor() {
|
||||
this.link = $("link[rel='canonical']").attr("href") || "None";
|
||||
this.id = this.link.split("/")[3] || "None";
|
||||
this.title = $("meta[property='og:title']").attr("content") || "None";
|
||||
this.image = $("meta[property='og:image']").attr("content") || "None";
|
||||
this.duration = $("meta[property='og:video:duration']").attr("content") || "0";
|
||||
this.views = $("span.video_view_count").text() || "None";
|
||||
this.rating = $("div.rating_percent.js_rating_percent").attr("data-percent") + "%" || "None";
|
||||
this.publish = $("span.video-infobox-date-added").text().replace("Published on ", "") || "None";
|
||||
this.upVote = this.rating;
|
||||
this.downVote = null;
|
||||
this.video = $("meta[name='twitter:player']").attr("content") || "None";
|
||||
this.tags = $("a.item.video_carousel_item.video_carousel_category, a.item.video_carousel_item.video_carousel_tag")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.tags = this.tags.map((el) => lust.removeHtmlTagWithoutSpace(el));
|
||||
this.models = $("div.pornstar-name.pornstarPopupWrapper")
|
||||
.find("a")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}
|
||||
).get();
|
||||
this.models = this.models.map((el) => lust.removeHtmlTagWithoutSpace(el));
|
||||
this.models = this.models.filter((el) => !el.includes("Subscribe") && !el.includes("Rank"))
|
||||
.filter((el, i, arr) => arr.indexOf(el) === i);
|
||||
}
|
||||
}
|
||||
|
||||
const red = new RedTube();
|
||||
const data: IVideoData = {
|
||||
success: true,
|
||||
data: {
|
||||
title: lust.removeHtmlTagWithoutSpace(red.title),
|
||||
id: red.id,
|
||||
image: red.image,
|
||||
duration: lust.secondToMinute(Number(red.duration)),
|
||||
views: red.views,
|
||||
rating: red.rating,
|
||||
uploaded: red.publish,
|
||||
upvoted: red.upVote,
|
||||
downvoted: red.downVote,
|
||||
models: red.models,
|
||||
tags: red.tags
|
||||
},
|
||||
source: red.link,
|
||||
assets: [red.video, red.image]
|
||||
};
|
||||
return data;
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class RedTubeSearch {
|
||||
views: string[];
|
||||
search: object[];
|
||||
data: object;
|
||||
constructor() {
|
||||
this.views = $("span.video_count")
|
||||
.map((i, el) => {
|
||||
const views = $(el).text();
|
||||
return views;
|
||||
}).get();
|
||||
this.search = $("a.video_link")
|
||||
.map((i, el) => {
|
||||
const link = $(el).attr("href");
|
||||
const id = link?.split("/")[1];
|
||||
const title = $(el).find("img").attr("alt");
|
||||
const image = $(el).find("img").attr("data-src");
|
||||
const duration = $(el).find("span.duration").text().split(" ").map((el: string) => {
|
||||
return el.replace(/[^0-9:]/g, "");
|
||||
}).filter((el: string) => {
|
||||
return el.includes(":");
|
||||
}).join(" ");
|
||||
|
||||
return {
|
||||
link: `${c.REDTUBE}${link}`,
|
||||
id: id,
|
||||
title: title,
|
||||
image: image,
|
||||
duration: duration,
|
||||
views: this.views[i],
|
||||
video: `https://embed.redtube.com/?id=${id}`,
|
||||
|
||||
};
|
||||
}).get();
|
||||
|
||||
|
||||
|
||||
|
||||
this.data = this.search.filter((el: any) => {
|
||||
return el.link.includes("javascript:void(0)") === false && el.image?.startsWith("data:image") === false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const red = new RedTubeSearch();
|
||||
|
||||
if (red.search.length === 0) throw Error("No result found");
|
||||
const data = red.data as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { IVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const resolve = await lust.fetchBody(url);
|
||||
const $ = load(resolve);
|
||||
|
||||
class Xhamster {
|
||||
link: string;
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
duration: any;
|
||||
views: string;
|
||||
rating: string;
|
||||
publish: string;
|
||||
upVote: string;
|
||||
downVote: string;
|
||||
video: string;
|
||||
tags: string[];
|
||||
models: string[];
|
||||
constructor() {
|
||||
this.link = $("link[rel='canonical']").attr("href") || "None";
|
||||
this.id = this.link.split("/")[3] + "/" + this.link.split("/")[4] || "None";
|
||||
this.title = $("meta[property='og:title']").attr("content") || "None";
|
||||
this.image = $("meta[property='og:image']").attr("content") || "None";
|
||||
this.duration = $("script#initials-script").html() || "None";
|
||||
//remove window.initials={ and };
|
||||
this.duration = this.duration.replace("window.initials=", "");
|
||||
this.duration = this.duration.replace(/;/g, "");
|
||||
this.duration = JSON.parse(this.duration);
|
||||
this.duration = this.duration.videoModel.duration || "None";
|
||||
this.views = $("div.header-icons").find("span").first().text() || "None";
|
||||
this.rating = $("div.header-icons").find("span").eq(1).text() || "None";
|
||||
this.publish = $("div.entity-info-container__date").attr("data-tooltip") || "None";
|
||||
this.upVote = $("div.rb-new__info").text().split("/")[0].trim() || "None";
|
||||
this.downVote = $("div.rb-new__info").text().split("/")[1].trim() || "None";
|
||||
this.video = "https://xheve2.com/embed/" + this.link.split("-").pop() || "None";
|
||||
this.tags = $("a.video-tag")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.tags = this.tags.map((el) => lust.removeHtmlTagWithoutSpace(el));
|
||||
this.models = $("a.video-tag")
|
||||
.map((i, el) => {
|
||||
return $(el).attr("href");
|
||||
}
|
||||
).get();
|
||||
this.models = this.models.filter((el) => el.startsWith("https://xheve2.com/pornstars/"));
|
||||
this.models = this.models.map((el) => el.replace("https://xheve2.com/pornstars/", ""));
|
||||
}
|
||||
}
|
||||
|
||||
const xh = new Xhamster();
|
||||
const data: IVideoData = {
|
||||
success: true,
|
||||
data: {
|
||||
title: lust.removeHtmlTagWithoutSpace(xh.title),
|
||||
id: xh.id,
|
||||
image: xh.image,
|
||||
duration: lust.secondToMinute(Number(xh.duration)),
|
||||
views: xh.views,
|
||||
rating: xh.rating,
|
||||
uploaded: xh.publish,
|
||||
upvoted: xh.upVote,
|
||||
downvoted: xh.downVote,
|
||||
models: xh.models,
|
||||
tags: xh.tags
|
||||
},
|
||||
source: xh.link,
|
||||
assets: [xh.video, xh.image]
|
||||
};
|
||||
return data;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class XhamsterSearch {
|
||||
search: any;
|
||||
constructor() {
|
||||
const views = $("div.video-thumb-views")
|
||||
.map((i, el) => {
|
||||
const views = $(el).text();
|
||||
return views;
|
||||
}).get();
|
||||
const duration = $("span[data-role='video-duration']")
|
||||
.map((i, el) => {
|
||||
const duration = $(el).text();
|
||||
return duration;
|
||||
}).get();
|
||||
this.search = $("a.video-thumb__image-container")
|
||||
.map((i, el) => {
|
||||
const link = $(el).attr("href");
|
||||
|
||||
return {
|
||||
link: `${link}`,
|
||||
id: link?.split("/")[3] + "/" + link?.split("/")[4],
|
||||
title: $(el).find("img").attr("alt"),
|
||||
image: $(el).find("img").attr("src"),
|
||||
duration: duration[i],
|
||||
views: views[i],
|
||||
video: $(el).attr("data-previewvideo"),
|
||||
};
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const xh = new XhamsterSearch();
|
||||
if (xh.search.length === 0) throw Error("No result found");
|
||||
const data = xh.search as unknown as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { IVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
console.log(url);
|
||||
const resolve = await lust.fetchBody(url);
|
||||
const $ = load(resolve);
|
||||
|
||||
class Xnxx {
|
||||
link: string;
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
duration: string;
|
||||
views: string;
|
||||
uploaded: string;
|
||||
action: string[];
|
||||
upVote: string;
|
||||
downVote: string;
|
||||
favVote: string;
|
||||
tags: string[];
|
||||
models: string[];
|
||||
thumbnail: string;
|
||||
bigimg: string;
|
||||
video: string;
|
||||
constructor() {
|
||||
const thumb = $("script")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get()
|
||||
.filter((el) => el.includes("html5player.setThumbSlideBig"))[0] || "None";
|
||||
|
||||
this.thumbnail = thumb.match(/html5player.setThumbSlideBig\((.*?)\)/)?.[1] || "None";
|
||||
this.bigimg = thumb.match(/html5player.setThumbUrl169\((.*?)\)/)?.[1] || "None";
|
||||
this.video = thumb.match(/html5player.setVideoUrlHigh\((.*?)\)/)?.[1] || "None";
|
||||
this.link = $("meta[property='og:url']").attr("content") || "None";
|
||||
this.id = this.link.split(".com/")[1] || "None";
|
||||
this.title = $("meta[property='og:title']").attr("content") || "None";
|
||||
this.image = $("meta[property='og:image']").attr("content") || "None";
|
||||
this.duration = $("meta[property='og:duration']").attr("content") || "None";
|
||||
this.views = $("span.metadata").text() || "None";
|
||||
this.views = this.views.split("-")[2] || "None";
|
||||
this.uploaded = $("script[type='application/ld+json']").text() || "None";
|
||||
this.uploaded = this.uploaded
|
||||
.split("uploadDate")[1]
|
||||
.split("}")[0]
|
||||
.split(":")[1]
|
||||
.replace(/"/g, "")
|
||||
.replace(/,/g, "") || "None";
|
||||
this.action = $("span.vote-actions")
|
||||
.find("span.value")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
|
||||
this.upVote = this.action[0] || "None";
|
||||
this.downVote = this.action[1] || "None";
|
||||
this.favVote = $("span.rating-box.value").text() || "None";
|
||||
this.models = $("a.is-pornstar")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.tags = $("div.metadata-row.video-tags")
|
||||
.find("a")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const x = new Xnxx();
|
||||
|
||||
const data: IVideoData = {
|
||||
success: true,
|
||||
data: {
|
||||
title: lust.removeHtmlTagWithoutSpace(x.title),
|
||||
id: x.id,
|
||||
image: x.image,
|
||||
duration: lust.secondToMinute(Number(x.duration)),
|
||||
views: lust.removeHtmlTag(x.views),
|
||||
rating: x.favVote,
|
||||
uploaded: x.uploaded.trim(),
|
||||
upvoted: x.upVote,
|
||||
downvoted: x.downVote,
|
||||
models: x.models,
|
||||
tags: x.tags.filter((el) => el !== "Edit tags and models")
|
||||
},
|
||||
source: x.link,
|
||||
assets: lust.removeAllSingleQuoteOnArray([x.thumbnail, x.bigimg, x.video])
|
||||
};
|
||||
return data;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class PornhubSearch {
|
||||
search: object[];
|
||||
data: object;
|
||||
constructor() {
|
||||
// in <div id="video-player-bg"> get <script>var video_related=
|
||||
this.search = $("div#video-player-bg")
|
||||
.map((i, el) => {
|
||||
const script = $(el).find("script").html();
|
||||
const video_related = script?.split("var video_related=")[1];
|
||||
//stop and replace everything after the last ];
|
||||
const badJson = video_related?.split("];")[0] + "]";
|
||||
const actualResult = JSON.parse(String(badJson));
|
||||
const result = actualResult.map((el: any) => {
|
||||
return {
|
||||
link: `${c.XNXX}${el.u}`,
|
||||
id: el.u,
|
||||
title: el.t,
|
||||
image: el.i,
|
||||
duration: el.d,
|
||||
views: `${el.n}, ${el.r}`,
|
||||
video: null
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const x = new PornhubSearch();
|
||||
if (x.search.length === 0) throw Error("No result found");
|
||||
const data = x.search as unknown as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class PornhubSearch {
|
||||
search: object[];
|
||||
constructor() {
|
||||
this.search = $("div.mozaique > div")
|
||||
.map((i, el) => {
|
||||
return {
|
||||
link: `${c.XNXX}${$(el).find("a").attr("href")}`,
|
||||
id: $(el).find("a").attr("href"),
|
||||
title: $(el).find("div.thumb-under").text().split("\n")
|
||||
.map((el) => el.trim()).filter((el) => el !== "")[0],
|
||||
image: $(el).find("img").attr("data-src"),
|
||||
duration: $(el).find("div.thumb-under").text().split("\n")
|
||||
.map((el) => el.trim()).filter((el) => el !== "")[2],
|
||||
rating: $(el).find("div.thumb-under").text().split("\n")
|
||||
.map((el) => el.trim()).filter((el) => el !== "")[1],
|
||||
video: null
|
||||
|
||||
};
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const x = new PornhubSearch();
|
||||
if (x.search.length === 0) throw Error("No result found");
|
||||
const data = x.search as unknown as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { IVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const resolve = await lust.fetchBody(url);
|
||||
const $ = load(resolve);
|
||||
|
||||
class Xvideos {
|
||||
link: string;
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
duration: string;
|
||||
views: string;
|
||||
rating: string;
|
||||
publish: string;
|
||||
upVote: string;
|
||||
downVote: string;
|
||||
video: string;
|
||||
tags: string[];
|
||||
models: string[];
|
||||
thumbnail: string;
|
||||
bigimg: string;
|
||||
constructor() {
|
||||
this.link = $("meta[property='og:url']").attr("content") || "None";
|
||||
this.id = this.link.split("/")[3] + "/" + this.link.split("/")[4] || "None";
|
||||
this.title = $("meta[property='og:title']").attr("content") || "None";
|
||||
this.image = $("meta[property='og:image']").attr("content") || "None";
|
||||
this.duration = $("meta[property='og:duration']").attr("content") || "0";
|
||||
this.views = $("div#v-views").find("strong.mobile-hide").text() || "None";
|
||||
this.rating = $("span.rating-total-txt").text() || "None";
|
||||
this.publish = $("script[type='application/ld+json']").text() || "None";
|
||||
this.publish = this.publish
|
||||
.split("uploadDate")[1]
|
||||
.split("}")[0]
|
||||
.split(":")[1]
|
||||
.replace(/"/g, "")
|
||||
.replace(/,/g, "") || "None";
|
||||
this.upVote = $("span.rating-good-nbr").text() || "None";
|
||||
this.downVote = $("span.rating-bad-nbr").text() || "None";
|
||||
const thumb = $("script")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get()
|
||||
.filter((el) => el.includes("html5player.setThumbSlideBig"))[0] || "None";
|
||||
this.thumbnail = thumb.match(/html5player.setThumbSlideBig\((.*?)\)/)?.[1] || "None";
|
||||
this.bigimg = thumb.match(/html5player.setThumbUrl169\((.*?)\)/)?.[1] || "None";
|
||||
this.video = thumb.match(/html5player.setVideoUrlHigh\((.*?)\)/)?.[1] || "None";
|
||||
this.tags = $("a.is-keyword.btn.btn-default")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.models = $("li.model")
|
||||
.map((i, el) => {
|
||||
return $(el).find("a").attr("href") || "None";
|
||||
}
|
||||
).get();
|
||||
this.models = this.models.map((el) => el.split("/")[2]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const xv = new Xvideos();
|
||||
const data: IVideoData = {
|
||||
success: true,
|
||||
data: {
|
||||
title: lust.removeHtmlTagWithoutSpace(xv.title),
|
||||
id: xv.id,
|
||||
image: xv.image,
|
||||
duration: lust.secondToMinute(Number(xv.duration)),
|
||||
views: lust.removeHtmlTag(xv.views),
|
||||
rating: xv.rating,
|
||||
uploaded: xv.publish,
|
||||
upvoted: xv.upVote,
|
||||
downvoted: xv.downVote,
|
||||
models: xv.models,
|
||||
tags: xv.tags,
|
||||
},
|
||||
source: xv.link,
|
||||
assets: lust.removeAllSingleQuoteOnArray([xv.thumbnail, xv.bigimg, xv.video])
|
||||
};
|
||||
return data;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
console.log(url);
|
||||
|
||||
class XvideosSearch {
|
||||
search: object[];
|
||||
data: object;
|
||||
constructor() {
|
||||
this.search = $("div#video-player-bg")
|
||||
.map((i, el) => {
|
||||
const script = $(el).find("script").html();
|
||||
const video_related = script?.split("var video_related=")[1];
|
||||
const badJson = video_related?.split("];")[0] + "]";
|
||||
const actualResult = JSON.parse(String(badJson));
|
||||
const result = actualResult.map((el: any) => {
|
||||
return {
|
||||
link: `${c.XVIDEOS}${el.u}`,
|
||||
id: el.u,
|
||||
title: el.t,
|
||||
image: el.i,
|
||||
duration: el.d,
|
||||
views: `${el.n}, ${el.r}`,
|
||||
video: null
|
||||
};
|
||||
});
|
||||
return result;
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const x = new XvideosSearch();
|
||||
if (x.search.length === 0) throw Error("No result found");
|
||||
const data = x.search as unknown as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
console.log(url);
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class XvideosSearch {
|
||||
search: object[];
|
||||
constructor() {
|
||||
const data = $("div.thumb-under")
|
||||
.map((i, el) => {
|
||||
return {
|
||||
title: $(el).find("a").attr("title"),
|
||||
duration: $(el).find("span.duration")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get()[0],
|
||||
};
|
||||
}).get();
|
||||
this.search = $("div.mozaique.cust-nb-cols")
|
||||
.find("div.thumb")
|
||||
.map((i, el) => {
|
||||
return {
|
||||
link: `${c.XVIDEOS}${$(el).find("a").attr("href")}` || "None",
|
||||
id: $(el).find("a").attr("href") || "None",
|
||||
image: $(el).find("img").attr("data-src") || "None",
|
||||
title: data[i].title || "None",
|
||||
duration: data[i].duration === data[i + 1]?.duration
|
||||
? ""
|
||||
: data[i].duration || "None",
|
||||
rating: null,
|
||||
video: null
|
||||
};
|
||||
}).get();
|
||||
|
||||
this.search = this.search.filter((el: any) => {
|
||||
return !el.id.includes("THUMBNUM");
|
||||
});
|
||||
this.search = this.search.filter((el: any) => {
|
||||
return el.id.includes("/video");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const xv = new XvideosSearch();
|
||||
if (xv.search.length === 0) throw Error("No result found");
|
||||
const data = xv.search as unknown as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import { IVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const resolve = await lust.fetchBody(url);
|
||||
const $ = load(resolve);
|
||||
|
||||
class YouPorn {
|
||||
link: string;
|
||||
id: string;
|
||||
title: string;
|
||||
image: string;
|
||||
duration: string;
|
||||
views: string;
|
||||
rating: string;
|
||||
publish: string;
|
||||
upVote: string;
|
||||
downVote: null;
|
||||
video: string;
|
||||
tags: string[];
|
||||
models: string[];
|
||||
constructor() {
|
||||
this.link = $("link[rel='canonical']").attr("href") || "None";
|
||||
this.id = this.link.replace("https://www.youporn.com/watch/", "") || "None";
|
||||
this.title = $("meta[property='og:title']").attr("content") || "None";
|
||||
this.image = $("meta[property='og:image']").attr("content") || "None";
|
||||
this.duration = $("meta[property='video:duration']").attr("content") || "0";
|
||||
this.views = $("div.feature.infoValueBlock").find("div[data-value]").attr("data-value") || "0";
|
||||
this.rating = $("div.feature").find("span").text().replace(/[^0-9.,%]/g, "") || "0";
|
||||
this.publish = $("div.video-uploaded").find("span").text() || "None";
|
||||
this.upVote = this.views;
|
||||
this.downVote = null;
|
||||
this.video = `https://www.youporn.com/embed/${this.id}`;
|
||||
this.tags = $("a[data-espnode='category_tag'], a[data-espnode='porntag_tag']")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.models = $("a[data-espnode='pornstar_tag']")
|
||||
.map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const yp = new YouPorn();
|
||||
const data: IVideoData = {
|
||||
success: true,
|
||||
data: {
|
||||
title: lust.removeHtmlTagWithoutSpace(yp.title),
|
||||
id: yp.id,
|
||||
image: yp.image,
|
||||
duration: lust.secondToMinute(Number(yp.duration)),
|
||||
views: yp.views,
|
||||
rating: yp.rating,
|
||||
uploaded: yp.publish,
|
||||
upvoted: yp.upVote,
|
||||
downvoted: yp.downVote,
|
||||
models: yp.models,
|
||||
tags: yp.tags
|
||||
},
|
||||
source: yp.link,
|
||||
assets: [yp.video, yp.image]
|
||||
};
|
||||
return data;
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import { load } from "cheerio";
|
||||
import LustPress from "../../LustPress";
|
||||
import c from "../../utils/options";
|
||||
import { ISearchVideoData } from "../../interfaces";
|
||||
|
||||
const lust = new LustPress();
|
||||
|
||||
export async function scrapeContent(url: string) {
|
||||
try {
|
||||
const res = await lust.fetchBody(url);
|
||||
const $ = load(res);
|
||||
|
||||
class YouPornSearch {
|
||||
dur: string[];
|
||||
search: object[];
|
||||
constructor() {
|
||||
this.dur = $("div.video-duration").map((i, el) => {
|
||||
return $(el).text();
|
||||
}).get();
|
||||
this.search = $("a[href^='/watch/']")
|
||||
.map((i, el) => {
|
||||
const link = $(el).attr("href");
|
||||
const id = `${link}`.split("/")[2] + "/" + `${link}`.split("/")[3];
|
||||
const title = $(el).find("div.video-box-title").text();
|
||||
const image = $(el).find("img").attr("data-thumbnail");
|
||||
return {
|
||||
link: `${c.YOUPORN}${link}`,
|
||||
id: id,
|
||||
title: lust.removeHtmlTagWithoutSpace(title),
|
||||
image: image,
|
||||
duration: this.dur[i],
|
||||
views: null,
|
||||
video: `https://www.youporn.com/embed/${id}`,
|
||||
};
|
||||
}).get();
|
||||
}
|
||||
}
|
||||
|
||||
const yp = new YouPornSearch();
|
||||
if (yp.search.length === 0) throw Error("No result found");
|
||||
const data = yp.search as unknown as string[];
|
||||
const result: ISearchVideoData = {
|
||||
success: true,
|
||||
data: data,
|
||||
source: url,
|
||||
};
|
||||
return result;
|
||||
|
||||
} catch (err) {
|
||||
const e = err as Error;
|
||||
throw Error(e.message);
|
||||
}
|
||||
}
|
読み込み中…
新しいイシューから参照