Added Dorcel Club with scene and actor scraping. Added count method to qu.
|
@ -178,7 +178,7 @@ function initEntitiesActions(store, router) {
|
|||
$entitySlugs: [String!] = []
|
||||
) {
|
||||
entities(
|
||||
orderBy: NAME_ASC
|
||||
orderBy: SLUG_ASC
|
||||
filter: {
|
||||
or: [
|
||||
{
|
||||
|
|
|
@ -113,6 +113,7 @@ module.exports = {
|
|||
],
|
||||
'21sextury',
|
||||
'julesjordan',
|
||||
'dorcelclub',
|
||||
'bang',
|
||||
'pervcity',
|
||||
'kink',
|
||||
|
@ -153,20 +154,22 @@ module.exports = {
|
|||
'pervertgallery',
|
||||
'povperverts',
|
||||
],
|
||||
'pascalssubsluts',
|
||||
'kellymadison',
|
||||
'private',
|
||||
'ddfnetwork',
|
||||
'bangbros',
|
||||
'hitzefrei',
|
||||
[
|
||||
'silverstonedvd',
|
||||
'silviasaint',
|
||||
],
|
||||
'porncz',
|
||||
'czechav',
|
||||
'gangbangcreampie',
|
||||
'gloryholesecrets',
|
||||
'aziani',
|
||||
'legalporno',
|
||||
[
|
||||
'silverstonedvd',
|
||||
'silviasaint',
|
||||
],
|
||||
'score',
|
||||
'boobpedia',
|
||||
'pornhub',
|
||||
|
|
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 170 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 18 KiB |
|
@ -1057,6 +1057,11 @@ const aliases = [
|
|||
for: 'bts',
|
||||
secondary: true,
|
||||
},
|
||||
{
|
||||
name: 'making of',
|
||||
for: 'bts',
|
||||
secondary: true,
|
||||
},
|
||||
{
|
||||
name: 'mfm',
|
||||
for: 'mmf',
|
||||
|
|
|
@ -148,6 +148,11 @@ const networks = [
|
|||
name: 'CzechAV',
|
||||
url: 'https://www.czechav.com',
|
||||
},
|
||||
{
|
||||
slug: 'dorcel',
|
||||
name: 'Marc Dorcel',
|
||||
url: 'https://www.dorcel.com',
|
||||
},
|
||||
{
|
||||
slug: 'fcuk',
|
||||
name: 'Fcuk',
|
||||
|
|
|
@ -2182,6 +2182,13 @@ const sites = [
|
|||
description: '',
|
||||
parent: 'dogfartnetwork',
|
||||
},
|
||||
// DORCEL
|
||||
{
|
||||
slug: 'dorcelclub',
|
||||
name: 'Dorcel Club',
|
||||
url: 'https://www.dorcelclub.com',
|
||||
parent: 'dorcel',
|
||||
},
|
||||
// ELEGANT ANGEL
|
||||
{
|
||||
slug: 'elegantangel',
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
'use strict';
|
||||
|
||||
const qu = require('../utils/q');
|
||||
const slugify = require('../utils/slugify');
|
||||
|
||||
function scrapeAll(scenes) {
|
||||
return scenes.map(({ query }) => {
|
||||
const release = {};
|
||||
|
||||
release.url = query.url('.title a');
|
||||
release.entryId = new URL(release.url).pathname.match(/\/scene\/(\d+)/)[1];
|
||||
|
||||
release.title = query.cnt('.title a');
|
||||
|
||||
release.date = query.date('.date', 'MMMM DD, YYYY', /\w+ \d{1,2}, \d{4}/);
|
||||
release.duration = query.number('.length') * 60;
|
||||
|
||||
release.actors = query.all('.actors a').map(actorEl => ({
|
||||
name: query.cnt(actorEl),
|
||||
url: query.url(actorEl, null),
|
||||
}));
|
||||
|
||||
release.poster = query.img('.poster noscript img');
|
||||
release.stars = query.count('.rating .star1');
|
||||
|
||||
release.tags = [query.cnt('.collection a')];
|
||||
|
||||
return release;
|
||||
});
|
||||
}
|
||||
|
||||
function scrapeScene({ query }, url) {
|
||||
const release = {};
|
||||
|
||||
release.entryId = new URL(url).pathname.match(/\/scene\/(\d+)/)[1];
|
||||
|
||||
release.title = query.cnt('.infos .title h1');
|
||||
release.description = query.cnt('#description p:nth-child(2)');
|
||||
|
||||
release.date = query.date('.infos .date', 'MMMM DD, YYYY', /\w+ \d{1,2}, \d{4}/);
|
||||
release.duration = query.number('.infos .length') * 60;
|
||||
|
||||
release.actors = query.all('.infos .actors a').map(actorEl => ({
|
||||
name: query.cnt(actorEl),
|
||||
url: query.url(actorEl, null),
|
||||
}));
|
||||
|
||||
release.poster = query.img('.poster noscript img');
|
||||
release.stars = query.count('.infos .rating .star1');
|
||||
|
||||
if (query.exists('.movie')) {
|
||||
release.movie = {
|
||||
name: query.cnt('.movie a'),
|
||||
url: query.url('.movie a'),
|
||||
};
|
||||
|
||||
release.movie.entryId = new URL(release.movie.url).pathname.split('/').slice(-1)[0];
|
||||
}
|
||||
|
||||
return release;
|
||||
}
|
||||
|
||||
function scrapeProfile({ query, el }, avatar) {
|
||||
const profile = {};
|
||||
|
||||
profile.birthdate = qu.parseDate(query.text('.birthdate'), 'MMMM DD, YYYY');
|
||||
profile.nationality = query.text('.nationality');
|
||||
profile.hairColor = query.text('.hair');
|
||||
|
||||
profile.description = query.cnt('.bio_results p');
|
||||
|
||||
if (avatar) {
|
||||
profile.avatar = [
|
||||
avatar.replace('_crop', ''),
|
||||
avatar,
|
||||
];
|
||||
}
|
||||
|
||||
// TODO: add pagination
|
||||
profile.releases = scrapeAll(qu.initAll(el, '.scene'));
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
// TODO: add movies
|
||||
|
||||
async function fetchLatest(channel, page = 1) {
|
||||
const url = `${channel.url}/en/news-videos-x-marc-dorcel-ajax?page=${page}&sorting=publish_date`;
|
||||
const res = await qu.getAll(url, '.scene', {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
return scrapeAll(res.items, channel);
|
||||
}
|
||||
|
||||
return res.status;
|
||||
}
|
||||
|
||||
async function fetchScene(url, channel) {
|
||||
const res = await qu.get(url);
|
||||
|
||||
if (res.ok) {
|
||||
return scrapeScene(res.item, url, channel);
|
||||
}
|
||||
|
||||
return res.status;
|
||||
}
|
||||
|
||||
async function fetchProfile({ name: actorName, url: actorUrl }, entity, include) {
|
||||
const searchRes = await qu.getAll(`${entity.url}/en/pornstars?search=${slugify(actorName, '+')}`, '.actor');
|
||||
|
||||
const actorItem = searchRes.ok && searchRes.items.find(actor => slugify(actor.query.cnt('h2')) === slugify(actorName));
|
||||
const actorItemUrl = actorItem?.query.url();
|
||||
const actorItemAvatar = actorItem?.query.img();
|
||||
|
||||
const url = actorUrl || actorItemUrl || `${entity.url}/en/pornstar/${slugify(actorName, '-')}`;
|
||||
const res = await qu.get(url);
|
||||
|
||||
if (res.ok) {
|
||||
return scrapeProfile(res.item, actorItemAvatar, entity, include);
|
||||
}
|
||||
|
||||
return res.status;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchLatest,
|
||||
fetchScene,
|
||||
fetchProfile,
|
||||
};
|
|
@ -65,7 +65,7 @@ function scrapeProfile({ query }) {
|
|||
profile.nationality = bio.nationality;
|
||||
profile.height = feetInchesToCm(bio.height);
|
||||
profile.age = bio.age;
|
||||
profile.hair = bio.hair;
|
||||
profile.hairColor = bio.hair;
|
||||
|
||||
profile.description = query.cnt('.twocolumns');
|
||||
profile.avatar = query.img('#individual-description img');
|
||||
|
|
|
@ -16,6 +16,7 @@ const czechav = require('./czechav');
|
|||
const ddfnetwork = require('./ddfnetwork');
|
||||
const digitalplayground = require('./digitalplayground');
|
||||
const dogfart = require('./dogfart');
|
||||
const dorcel = require('./dorcel');
|
||||
const elegantangel = require('./elegantangel');
|
||||
const evilangel = require('./evilangel');
|
||||
const fakehub = require('./fakehub');
|
||||
|
@ -100,6 +101,7 @@ module.exports = {
|
|||
digitalplayground,
|
||||
dogfart,
|
||||
dogfartnetwork: dogfart,
|
||||
dorcel,
|
||||
elegantangel,
|
||||
evilangel,
|
||||
fakehub,
|
||||
|
@ -189,6 +191,7 @@ module.exports = {
|
|||
devilsfilm: famedigital,
|
||||
digitalplayground,
|
||||
dtfsluts: fullpornnetwork,
|
||||
dorcelclub: dorcel,
|
||||
elegantangel,
|
||||
evilangel,
|
||||
eyeontheguy: hush,
|
||||
|
|
|
@ -95,6 +95,10 @@ function exists(context, selector) {
|
|||
return !!q(context, selector);
|
||||
}
|
||||
|
||||
function count(context, selector) {
|
||||
return all(context, selector)?.length || 0;
|
||||
}
|
||||
|
||||
function content(context, selector, applyTrim = true) {
|
||||
return q(context, selector, 'textContent', applyTrim);
|
||||
}
|
||||
|
@ -323,6 +327,7 @@ const quFuncs = {
|
|||
contents,
|
||||
cnt: content,
|
||||
cnts: contents,
|
||||
count,
|
||||
date,
|
||||
dateAgo,
|
||||
dur: duration,
|
||||
|
|