Skip to content

Instantly share code, notes, and snippets.

@donal56
Last active December 6, 2025 20:23
Show Gist options
  • Select an option

  • Save donal56/dc37300469cec5aa15d3deb0f12b3ad2 to your computer and use it in GitHub Desktop.

Select an option

Save donal56/dc37300469cec5aa15d3deb0f12b3ad2 to your computer and use it in GitHub Desktop.
(agumation-utilities) Descarga videos del aguringu FC. Es necesario agregar los enlaces en links.txt y las credenciales del sitio junto con la api key de deepl en properties.js. Youtube-dl debe estar instalado y disponible en el path.
const deepl = require('deepl-node');
const puppeteer = require('puppeteer');
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const fs = require('fs');
const properties = require('./properties.js');
// Datos del club
const baseUrl = "https://aguri-onishi.com";
const loginUrl = baseUrl + "/signin";
const { user, pass } = properties.aguringu;
// Datos de DeepL
const { apiKey } = properties.deepl;
const translator = new deepl.Translator(apiKey);
// Otras constantes
const iframeDomain = "player-api.p.uliza.jp";
const streamOrigin = "https://vms-api.p.uliza.jp/v1/prog-index.m3u8";
const indexPageIdentifier = "/categories/";
const seenStreams = new Set();
(async () => {
// Inicializar
printLn("===RUNNING===");
const browser = await puppeteer.launch({
headless: "new",
//devtools: true
});
const page = await browser.newPage();
// Iniciar sesión
await page.goto(loginUrl);
await page.waitForSelector('#jsLoadingAnimation', { hidden: true });
await page.click("#user_login");
await page.keyboard.type(user);
await page.click("#user_password");
await page.keyboard.type(pass);
await page.click(".signin-form + div input[type=submit]");
await page.waitForSelector('#mains')
.then(() => printLn("===LOGGED IN==="))
.catch(() => printLn("FAILED: Verify your credentials", 2));
// Escuchar solicitudes de red del frame del reproductor
page.on('framenavigated', async frame => {
try {
const frameClient = await frame._client();
await frameClient.send('Network.enable');
frameClient.on('Network.requestWillBeSent', request => {
const streamUrl = request.request.url;
if (streamUrl.startsWith(streamOrigin) && !seenStreams.has(streamUrl)) {
seenStreams.add(streamUrl);
printLn("Stream found", 3);
downloadVideo(page, streamUrl);
}
});
} catch (err) { }
});
// Visitar cada video
const urlsToDownload = await getLinksToDownload(page);
for (index in urlsToDownload) {
printLn("Start " + urlsToDownload[index]);
await page.goto(urlsToDownload[index]);
await page.waitForSelector('#jsLoadingAnimation', { hidden: true });
const iframeHandle = await page.waitForSelector(`iframe[src*="${iframeDomain}"]`);
const frame = await iframeHandle.contentFrame();
await frame.waitForSelector("video");
try {
await frame.waitForNavigation({timeout: 10_000, waitUntil: 'networkidle2'});
}
catch(err) {}
}
// Finalizar
await browser.close();
printLn("===END===", 3);
async function downloadVideo(page, videoUrl) {
// El formato es '#131_今年も一年'
const untranslatedTitle = await page.$eval(".title", el => el.textContent.trim().replace("_", " "));
const translationJob = await translator.translateText(untranslatedTitle, "JA", "EN-US");
// El formato es '2024.12.30'
const publishedDate = await page.$eval(".time", el => el.textContent.replaceAll(".", "-"));
// Comando final
const fileName = translationJob.text.replaceAll("\"", "'").replaceAll(".", "") + " " + publishedDate + ".mp4";
const filePath = "./downloads/" + fileName;
const command = "yt-dlp --referer " + baseUrl + " -o \"" + filePath + "\" \"" + videoUrl + "\"";
printLn(command, 3);
const {stdout, stderr } = await exec(command);
if (stderr) {
printLn("Error: " + stderr, 2);
}
else {
if (stdout.trim().endsWith("has already been downloaded")) {
printLn("Already downloaded, skipping", 3);
}
else {
printLn("Completed succesfully", 1);
}
}
}
async function getLinksToDownload(page) {
const file = fs.readFileSync('links.txt', 'utf-8');
const lines = file.split(/\r?\n/);
let expanded = [];
for (const link of lines) {
if (link.includes(indexPageIdentifier)) {
const subLinks = await detectIndexPageUrls(page, link);
expanded = [...expanded, ...subLinks];
} else {
expanded.push(link);
}
}
printLn("Links detected: " + expanded, 3)
return expanded;
}
async function detectIndexPageUrls(page, indexPageUrl) {
await page.goto(indexPageUrl);
await page.waitForSelector('#jsLoadingAnimation', { hidden: true });
const hrefs = await page.$$eval('.details-voice .thumb-list-item a', (nodes, baseUrl2) =>
nodes.map(a => new URL(a.getAttribute('href'), baseUrl2).href)
, baseUrl);
return hrefs;
}
})();
/**
* Print to console
* @param message
* @param style - color style of the message
* 0 - Primary
* 1 - Success
* 2 - Error
* 3 - Muted
*/
function printLn(message, style = 0) {
// Formatos de consola
const styleReset = "\x1b[0m";
const stylePrimary = "\x1b[42m%s\x1b[37m";
const styleSuccess = "\x1b[4m%s\x1b[32m";
const styleError = "\x1b[4m%s\x1b[31m";
const styleMuted = "\x1b[2m%s\x1b[4m";
const styles = [stylePrimary, styleSuccess, styleError, styleMuted];
console.info(styles[style], message, styleReset);
console.info("");
}
async function takeScreenshot(page) {
let url = page.url().replaceAll("/", "_");
url = url.replaceAll(":", "_");
await page.screenshot({ path: "ss_" + Date.now() + "_" + url + ".png" });
}
{
"dependencies": {
"deepl": "^1.0.13",
"deepl-node": "^1.7.1",
"puppeteer": "^19.2.2"
}
}
var properties = {
deepl : {
apiKey: "REPLACE_ME"
},
aguringu : {
user: "REPLACE_ME",
pass: "REPLACE_ME"
}
};
module.exports = properties;
@donal56
Copy link
Author

donal56 commented Dec 6, 2025

Requerimentos: ffmpeg
Instrucciones:

  1. Crea un archivo llamado links.txt y agrega los enlaces a descargar ahí. El script soporta paginas indexadas completas (p/e https://aguri-onishi.com/movies/categories/movie/page/2) o paginas de videos (p/e https://aguri-onishi.com/movies/84960).
  2. Remplaza tus credenciales en properties.js.
  3. Corre npm install.
  4. Ejecuta usando node aguringu-downloader.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment