Greasy Fork

Crunchyroll Arabic Episode Titles and Descriptions Extractor

Extract titles, episode numbers, and descriptions of all episodes on Crunchyroll and save them as JSON

当前为 2024-12-11 提交的版本,查看 最新版本

// ==UserScript==
// @name         Crunchyroll Arabic Episode Titles and Descriptions Extractor
// @namespace    https://greasyfork.org/en/scripts/518373-crunchyroll-arabic-episode-titles-and-descriptions-extractor
// @version      1.4
// @description  Extract titles, episode numbers, and descriptions of all episodes on Crunchyroll and save them as JSON
// @author       You
// @match        https://www.crunchyroll.com/ar/series/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // Function to download data as JSON file
    function downloadJSON(data, filename) {
        const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(data, null, 2));
        const downloadAnchorNode = document.createElement('a');
        downloadAnchorNode.setAttribute("href", dataStr);
        downloadAnchorNode.setAttribute("download", filename);
        document.body.appendChild(downloadAnchorNode);
        downloadAnchorNode.click();
        downloadAnchorNode.remove();
    }

    // Function to extract titles, episode numbers, and descriptions
    function extractEpisodeInfo() {
        const episodes = [];
        const elements = document.querySelectorAll('div[class*="playable-card-hover__body"]');

        elements.forEach(element => {
            const titleElement = element.querySelector('h4[data-t="episode-title"]');
            const descriptionElement = element.querySelector('p[data-t="description"]');

            if (titleElement && descriptionElement) {
                const titleText = titleElement.textContent.trim();
                const titleMatch = titleText.match(/ح(\d+)\s*-\s*(.*)/);
                if (titleMatch) {
                    const episodeNumber = titleMatch[1];
                    const episodeTitle = titleMatch[2];
                    const description = descriptionElement.textContent.trim();
                    episodes.push({ episodeNumber, episodeTitle, description });
                }
            }
        });

        console.log('Episodes:', episodes);
        downloadJSON(episodes, 'episodes_titles.json');
    }

    // Function to create and add the button to the page
    function createButton() {
        const button = document.createElement('button');
        button.id = 'episodeInfoButton'; // Add an ID to identify the button later
        button.innerHTML = 'Get Episodes Info';
        button.style.position = 'fixed';
        button.style.top = '10px';
        button.style.right = '10px';
        button.style.zIndex = '1000';
        button.style.padding = '10px 20px';
        button.style.backgroundColor = '#4CAF50';
        button.style.color = 'white';
        button.style.border = 'none';
        button.style.borderRadius = '5px';
        button.style.cursor = 'pointer';
        button.addEventListener('click', extractEpisodeInfo);
        document.body.appendChild(button);
    }

    // Observe the DOM for changes and ensure the button is present
    function ensureButtonPresence() {
        if (!document.getElementById('episodeInfoButton')) {
            createButton();
        }
    }

    // Add the button to the page when it loads
    window.addEventListener('load', createButton);

    // Observe DOM changes to re-add the button if it gets removed
    const observer = new MutationObserver(ensureButtonPresence);
    observer.observe(document.body, { childList: true, subtree: true });
})();