Added Little Caprice Dreams scraped (WIP).
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 8.3 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 291 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 356 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 872 KiB |
After Width: | Height: | Size: 4.5 MiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 1.6 MiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 33 KiB |
|
@ -1098,6 +1098,10 @@ const aliases = [
|
|||
for: 'bts',
|
||||
secondary: true,
|
||||
},
|
||||
{
|
||||
name: 'behind the scene',
|
||||
for: 'bts',
|
||||
},
|
||||
{
|
||||
name: 'blindfolded',
|
||||
for: 'blindfold',
|
||||
|
@ -1265,6 +1269,10 @@ const aliases = [
|
|||
name: 'couples fantasies',
|
||||
for: 'couples',
|
||||
},
|
||||
{
|
||||
name: 'couple sex',
|
||||
for: 'couples',
|
||||
},
|
||||
{
|
||||
name: 'creampies',
|
||||
for: 'creampie',
|
||||
|
|
|
@ -4225,6 +4225,13 @@ const sites = [
|
|||
url: 'https://letsdoeit.com/channels/bums-besuch.en.html',
|
||||
parent: 'letsdoeit',
|
||||
},
|
||||
// LITTLE CAPRICE
|
||||
{
|
||||
name: 'Little Caprice Dreams',
|
||||
slug: 'littlecapricedreams',
|
||||
alias: ['little caprice'],
|
||||
url: 'https://www.littlecaprice-dreams.com',
|
||||
},
|
||||
// MAMACITAZ
|
||||
{
|
||||
name: 'Her Big Ass',
|
||||
|
|
|
@ -694,12 +694,14 @@ const tagPhotos = [
|
|||
['anal', 3, 'Dakota Skye for Brazzers'],
|
||||
// ['anal', 1, 'Veronica Leal and Tina Kay in "Agents On Anal Mission" for Asshole Fever'],
|
||||
// ['anal', 0, 'Veronica Leal'],
|
||||
['anal-creampie', 3, 'Rose Valerie for Euro Sex Parties'],
|
||||
['anal-creampie', 0, 'Gina Valentina and Jane Wilde in "A Very Special Anniversary" for Tushy'],
|
||||
['anal-creampie', 1, 'Aleska Diamond in "Aleska Wants More" for Asshole Fever'],
|
||||
['ass-eating', 4, 'Vanna Bardot and Isiah Maxwell in "Vanna Craves Isiah\'s Cock!" for DarkX'],
|
||||
['ass-eating', 3, 'Abella Danger and Karma Rx in "Neon Dreaming" for Brazzers'],
|
||||
['ass-eating', 1, 'Aidra Fox and Cassidy Klein in "Lesbian Anal Yoga" for LesbianX'],
|
||||
['ass-eating', 0, 'Angelica Heart and Leanna Sweet in "ATM Bitches" for Asshole Fever'],
|
||||
['anal-fingering', 3, 'Rose Valerie for DDF Network'],
|
||||
['anal-fingering', 1, 'Cherry Kiss, Veronica Leal and Sybil in "Capture This" for Lez Cuties'],
|
||||
['anal-fingering', 2, 'Aidra Fox and Cassidy Klein in "Lesbian Anal Yoga" for LesbianX'],
|
||||
['bts', 0, 'Janice Griffith in "Day With A Pornstar: Janice" for Brazzers'],
|
||||
|
@ -708,6 +710,8 @@ const tagPhotos = [
|
|||
['blonde', 3, 'Kylie Page in "A Juicy Afternoon Delight" for New Sensations'],
|
||||
['blonde', 2, 'Isabelle Deltore for Her Limit'],
|
||||
['blowbang', 'poster', 'Marsha May in "Feeding Frenzy 12" for Jules Jordan'],
|
||||
['blowjob', 3, 'Rose Valie for Hands On Hardcore'],
|
||||
['blowjob', 2, 'Luna Kitsuen in "Gag Reflex" for Evil Angel'],
|
||||
['blowjob', 1, 'Kylie Page in "Stepsis Gives Soapy Handjob In Shower" for Spy Fam'],
|
||||
// ['bukkake', 'poster', 'Mia Malkova in "Facialized 2" for HardX'],
|
||||
['caucasian', 0, 'Remy Lacroix for HardX'],
|
||||
|
@ -819,6 +823,7 @@ const tagPhotos = [
|
|||
['maid', 1, 'Alessandra Jane for Brazzers'],
|
||||
// ['milf', 0, 'Olivia Austin in "Dredd 3" for Jules Jordan'],
|
||||
['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'],
|
||||
['mfm', 7, 'Rose Valerie for Euro Sex Parties'],
|
||||
['mfm', 1, 'Lana Rhoades in "Gangbang Me 3" for HardX'],
|
||||
['mfm', 6, 'Honey Gold in "Slut Puppies 12" for Jules Jordan'],
|
||||
['natural-boobs', 1, 'Nia Nacci for First Class POV'],
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
const qu = require('../utils/qu');
|
||||
|
||||
function scrapeAll(scenes) {
|
||||
return scenes.map(({ query, el }) => {
|
||||
const release = {};
|
||||
|
||||
release.url = query.url('a');
|
||||
release.entryId = query.q(el, null, 'id')?.match(/post-(\d+)/)?.[1];
|
||||
|
||||
release.title = query.cnt('.meta h3');
|
||||
release.date = query.date('.meta .post-meta', 'MMMM D, YYYY');
|
||||
|
||||
release.poster = query.img('img');
|
||||
|
||||
return release;
|
||||
});
|
||||
}
|
||||
|
||||
function scrapeScene({ query }) {
|
||||
const release = {};
|
||||
|
||||
const script = query.cnt('script.yoast-schema-graph');
|
||||
const data = script && JSON.parse(script);
|
||||
|
||||
release.entryId = query.q('article.project', 'id')?.match(/post-(\d+)/)?.[1];
|
||||
|
||||
release.title = query.cnt('.vid_title');
|
||||
release.description = query.cnt('.vid_desc p');
|
||||
|
||||
release.date = query.date('.vid_date', 'MMMM D, YYYY');
|
||||
release.duration = query.dur('.vid_length');
|
||||
|
||||
release.actors = query.all('.vid_infos a[href*="author/"]').map(actorEl => ({
|
||||
name: query.cnt(actorEl),
|
||||
url: query.url(actorEl, null),
|
||||
}));
|
||||
|
||||
release.tags = query.cnts('.vid_infos a[rel="tag"]');
|
||||
|
||||
const posterData = data['@graph']?.find(item => item['@type'] === 'ImageObject');
|
||||
|
||||
release.poster = posterData?.url
|
||||
|| query.q('meta[property="og:image"]', 'content')
|
||||
|| query.q('meta[name="twitter:image"]', 'content');
|
||||
|
||||
release.stars = Math.min(Number(query.q('.post-ratings-image', 'title')?.match(/average:\s*(\d\.\d+)/)?.[1]), 5) || null; // rating out of 5, yet sometimes 5.07?
|
||||
|
||||
// TODO: photo gallery, find if any video has a trailer
|
||||
console.log(release);
|
||||
return release;
|
||||
}
|
||||
|
||||
async function fetchLatest(channel) {
|
||||
// no apparent pagination, all updates on one page
|
||||
const res = await qu.getAll(`${channel.url}/videos/`, '.project');
|
||||
|
||||
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, channel);
|
||||
}
|
||||
|
||||
return res.status;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchLatest,
|
||||
fetchScene,
|
||||
};
|
|
@ -38,6 +38,7 @@ const kellymadison = require('./kellymadison');
|
|||
const killergram = require('./killergram');
|
||||
const kink = require('./kink');
|
||||
const legalporno = require('./legalporno');
|
||||
const littlecapricedreams = require('./littlecapricedreams');
|
||||
const porndoe = require('./porndoe');
|
||||
const men = require('./men');
|
||||
const metrohd = require('./metrohd');
|
||||
|
@ -53,7 +54,6 @@ const perfectgonzo = require('./perfectgonzo');
|
|||
const pervcity = require('./pervcity');
|
||||
const porncz = require('./porncz');
|
||||
const pornhub = require('./pornhub');
|
||||
const whalemember = require('./whalemember');
|
||||
const pascalssubsluts = require('./pascalssubsluts'); // reserved keyword
|
||||
const privateNetwork = require('./private'); // reserved keyword
|
||||
const puretaboo = require('./puretaboo');
|
||||
|
@ -69,6 +69,7 @@ const twistys = require('./twistys');
|
|||
const vivid = require('./vivid');
|
||||
const vixen = require('./vixen');
|
||||
const vogov = require('./vogov');
|
||||
const whalemember = require('./whalemember');
|
||||
const wicked = require('./wicked');
|
||||
const xempire = require('./xempire');
|
||||
const zerotolerance = require('./zerotolerance');
|
||||
|
@ -128,6 +129,7 @@ const scrapers = {
|
|||
kink,
|
||||
legalporno,
|
||||
letsdoeit: porndoe,
|
||||
littlecapricedreams,
|
||||
mamacitaz: porndoe,
|
||||
men,
|
||||
metrohd,
|
||||
|
|
|
@ -9,6 +9,7 @@ const Bottleneck = require('bottleneck');
|
|||
const { JSDOM } = require('jsdom');
|
||||
|
||||
const logger = require('../logger')(__filename);
|
||||
const virtualConsole = require('./virtual-console')(__filename);
|
||||
const argv = require('../argv');
|
||||
|
||||
const pipeline = util.promisify(stream.pipeline);
|
||||
|
@ -105,7 +106,7 @@ async function request(method = 'get', url, body, requestOptions = {}, limiter)
|
|||
|
||||
if (Buffer.isBuffer(res.body)) {
|
||||
const html = res.body.toString();
|
||||
const window = new JSDOM(html).window;
|
||||
const window = new JSDOM(html, { virtualConsole }).window;
|
||||
|
||||
return {
|
||||
...res,
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
const { JSDOM } = require('jsdom');
|
||||
const moment = require('moment');
|
||||
const http = require('./http');
|
||||
const virtualConsole = require('./virtual-console')(__filename);
|
||||
|
||||
const { window: globalWindow } = new JSDOM('');
|
||||
const { window: globalWindow } = new JSDOM('', { virtualConsole });
|
||||
|
||||
function trim(str) {
|
||||
if (typeof str !== 'string') {
|
||||
|
@ -440,7 +441,7 @@ function initAll(context, selector, window) {
|
|||
}
|
||||
|
||||
function extract(htmlValue, selector) {
|
||||
const { window } = new JSDOM(htmlValue);
|
||||
const { window } = new JSDOM(htmlValue, { virtualConsole });
|
||||
|
||||
if (selector) {
|
||||
return init(window.document.querySelector(selector), window);
|
||||
|
@ -450,7 +451,7 @@ function extract(htmlValue, selector) {
|
|||
}
|
||||
|
||||
function extractAll(htmlValue, selector) {
|
||||
const { window } = new JSDOM(htmlValue);
|
||||
const { window } = new JSDOM(htmlValue, { virtualConsole });
|
||||
|
||||
return initAll(window.document, selector, window);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
const { VirtualConsole } = require('jsdom');
|
||||
const path = require('path');
|
||||
|
||||
const logger = require('../logger')(__filename);
|
||||
|
||||
function getVirtualConsole(filepath) {
|
||||
const virtualConsole = new VirtualConsole();
|
||||
const context = path.basename(filepath);
|
||||
|
||||
virtualConsole.on('error', message => logger.warn(`Error from JSDOM in ${context}: ${message}`));
|
||||
virtualConsole.on('jsdomError', message => logger.warn(`Error from JSDOM in ${context}: ${message}`));
|
||||
|
||||
return virtualConsole;
|
||||
}
|
||||
|
||||
module.exports = getVirtualConsole;
|