Refactored PornCZ scraper. Renamed Brutal Sessions to Dungeon Sex.

This commit is contained in:
DebaucheryLibrarian
2026-01-13 20:52:31 +01:00
parent 725087bf1c
commit c64c4dd694
5 changed files with 171 additions and 164 deletions

View File

@@ -299,6 +299,37 @@ async function scrapeApiReleases(json, site, options) {
});
}
async function fetchLatestApi(site, page = 1, options, _preData, upcoming = false) {
const referer = options.parameters?.referer || `${options.parameters?.networkReferer ? site.parent.url : site.url}/en/videos`;
const { apiUrl } = await fetchApiCredentials(referer, site);
const slug = options.parameters.querySlug || site.slug;
const params = `query=&hitsPerPage=36&maxValuesPerFacet=100&page=${page - 1}&facetFilters=[["lesbian:"],["bisex:"],["shemale:"],["upcoming:${upcoming ? 1 : 0}"]]${options.parameters.queryChannel
? `&filters=channels.id:${options.parameters.queryChannel === true ? slug : options.parameters.queryChannel}`
: `&filters=availableOnSite:${slug}`}`;
const res = await http.post(apiUrl, {
requests: [
{
indexName: 'all_scenes',
params,
},
],
}, {
headers: {
Referer: referer,
},
}, {
encodeJSON: true,
});
if (res.status === 200 && res.body.results?.[0]?.hits) {
return scrapeApiReleases(res.body.results[0].hits, site, options);
}
return res.status;
}
function scrapeAll(scenes, site, networkUrl, hasTeaser = true) {
return scenes.map(({ query, el }) => {
const release = {};
@@ -328,6 +359,54 @@ function scrapeAll(scenes, site, networkUrl, hasTeaser = true) {
});
}
function getLatestUrl(site, page) {
if (site.parameters?.latest) {
if (/^http/.test(site.parameters.latest)) {
return /%d/.test(site.parameters.latest)
? util.format(site.parameters.latest, page)
: `${site.parameters.latest}${page}`;
}
return /%d/.test(site.parameters.latest)
? util.format(`${site.url}${site.parameters.latest}`, page)
: `${site.url}${site.parameters.latest}${page}`;
}
return `${site.url}/en/videos/AllCategories/0/${page}`;
}
function getUpcomingUrl(site) {
if (site.parameters?.upcoming) {
return /^http/.test(site.parameters.upcoming)
? `${site.parameters.upcoming}`
: `${site.url}${site.parameters.upcoming}`;
}
return `${site.url}/en/videos/AllCategories/0/1/upcoming`;
}
async function fetchLatest(site, page = 1) {
const url = getLatestUrl(site, page);
const res = await qu.getAll(url, 'li[data-itemtype=scene], div[data-itemtype*=scene]');
if (res.ok) {
return scrapeAll(res.items, site);
}
return res.status;
}
async function fetchUpcoming(site) {
const url = getUpcomingUrl(site);
const res = await qu.getAll(url, 'li[data-itemtype=scene], div[data-itemtype*=scene]');
if (res.ok) {
return scrapeAll(res.items, site, null, false);
}
return res.status;
}
async function scrapeScene({ query }, url, channel, baseRelease, mobileItem, options) {
const release = { query }; // used by XEmpire scraper to resolve channel-specific details
@@ -658,37 +737,6 @@ function scrapeApiProfile(data, releases, siteSlug) {
return profile;
}
async function fetchLatestApi(site, page = 1, options, _preData, upcoming = false) {
const referer = options.parameters?.referer || `${options.parameters?.networkReferer ? site.parent.url : site.url}/en/videos`;
const { apiUrl } = await fetchApiCredentials(referer, site);
const slug = options.parameters.querySlug || site.slug;
const params = `query=&hitsPerPage=36&maxValuesPerFacet=100&page=${page - 1}&facetFilters=[["lesbian:"],["bisex:"],["shemale:"],["upcoming:${upcoming ? 1 : 0}"]]${options.parameters.queryChannel
? `&filters=channels.id:${options.parameters.queryChannel === true ? slug : options.parameters.queryChannel}`
: `&filters=availableOnSite:${slug}`}`;
const res = await http.post(apiUrl, {
requests: [
{
indexName: 'all_scenes',
params,
},
],
}, {
headers: {
Referer: referer,
},
}, {
encodeJSON: true,
});
if (res.status === 200 && res.body.results?.[0]?.hits) {
return scrapeApiReleases(res.body.results[0].hits, site, options);
}
return res.status;
}
async function fetchUpcomingApi(site, page = 1, options, preData) {
return fetchLatestApi(site, page, options, preData, true);
}
@@ -771,54 +819,6 @@ async function fetchMovieApi(url, site, baseRelease, options) {
return res.status;
}
function getLatestUrl(site, page) {
if (site.parameters?.latest) {
if (/^http/.test(site.parameters.latest)) {
return /%d/.test(site.parameters.latest)
? util.format(site.parameters.latest, page)
: `${site.parameters.latest}${page}`;
}
return /%d/.test(site.parameters.latest)
? util.format(`${site.url}${site.parameters.latest}`, page)
: `${site.url}${site.parameters.latest}${page}`;
}
return `${site.url}/en/videos/AllCategories/0/${page}`;
}
function getUpcomingUrl(site) {
if (site.parameters?.upcoming) {
return /^http/.test(site.parameters.upcoming)
? `${site.parameters.upcoming}`
: `${site.url}${site.parameters.upcoming}`;
}
return `${site.url}/en/videos/AllCategories/0/1/upcoming`;
}
async function fetchLatest(site, page = 1) {
const url = getLatestUrl(site, page);
const res = await qu.getAll(url, 'li[data-itemtype=scene], div[data-itemtype*=scene]');
if (res.ok) {
return scrapeAll(res.items, site);
}
return res.status;
}
async function fetchUpcoming(site) {
const url = getUpcomingUrl(site);
const res = await qu.getAll(url, 'li[data-itemtype=scene], div[data-itemtype*=scene]');
if (res.ok) {
return scrapeAll(res.items, site, null, false);
}
return res.status;
}
function getDeepUrl(url, site, baseRelease, mobile) {
const filter = new Set(['en', 'video', 'scene', site.slug, site.parent.slug]);
const pathname = baseRelease?.path || new URL(url).pathname