Skip to content

Instantly share code, notes, and snippets.

@devinschumacher
Last active November 28, 2025 08:48
Show Gist options
  • Select an option

  • Save devinschumacher/26be6111dddf12e6ce02d236e2bc1385 to your computer and use it in GitHub Desktop.

Select an option

Save devinschumacher/26be6111dddf12e6ce02d236e2bc1385 to your computer and use it in GitHub Desktop.
How to bulk download all the videos in a skool classroom

How to bulk download all the videos in a skool classroom

step 1 - get the course URLs

// Extract all lesson URLs from Skool classroom - paste in browser console
function extractAllLessonUrls() {
    console.log("πŸ” Searching for lesson URLs on this page...");
    
    const urls = new Set();
    
    // Dynamically get base URL from current page
    const currentUrl = new URL(window.location.href);
    const baseUrl = `${currentUrl.protocol}//${currentUrl.host}${currentUrl.pathname}`;
    
    console.log(`πŸ“ Auto-detected base URL: ${baseUrl}`);
    console.log(`🌐 Current full URL: ${window.location.href}`);
    
    // Method 1: Look for direct links with md= parameters
    document.querySelectorAll('a[href*="classroom"]').forEach(link => {
        if (link.href.includes('md=')) {
            urls.add(link.href);
            console.log("Found link:", link.href);
        }
    });
    
    // Method 2: Look for any links containing md= in any attribute  
    document.querySelectorAll('*').forEach(el => {
        // Check onclick handlers
        const onclick = el.getAttribute('onclick');
        if (onclick && onclick.includes('md=')) {
            const mdMatch = onclick.match(/md=([a-f0-9]+)/);
            if (mdMatch) {
                const url = `${baseUrl}?md=${mdMatch[1]}`;
                urls.add(url);
                console.log("Found in onclick:", url);
            }
        }
        
        // Check data attributes
        ['data-href', 'data-url', 'data-link', 'data-md'].forEach(attr => {
            const value = el.getAttribute(attr);
            if (value && value.includes('md=')) {
                if (value.startsWith('http')) {
                    urls.add(value);
                } else {
                    const mdMatch = value.match(/md=([a-f0-9]+)/);
                    if (mdMatch) {
                        const url = `${baseUrl}?md=${mdMatch[1]}`;
                        urls.add(url);
                        console.log(`Found in ${attr}:`, url);
                    }
                }
            }
        });
        
        // Check for md= in any attribute value
        for (let attr of el.attributes) {
            if (attr.value.includes('md=') && !attr.name.startsWith('data-react')) {
                const mdMatch = attr.value.match(/md=([a-f0-9]+)/g);
                if (mdMatch) {
                    mdMatch.forEach(match => {
                        const mdValue = match.replace('md=', '');
                        const url = `${baseUrl}?md=${mdValue}`;
                        urls.add(url);
                        console.log(`Found in ${attr.name}:`, url);
                    });
                }
            }
        }
    });
    
    // Method 3: Look in page source/innerHTML for md= patterns
    const pageSource = document.documentElement.innerHTML;
    const mdMatches = pageSource.match(/md=([a-f0-9]{32})/g);
    if (mdMatches) {
        mdMatches.forEach(match => {
            const mdValue = match.replace('md=', '');
            const url = `${baseUrl}?md=${mdValue}`;
            urls.add(url);
        });
        console.log(`Found ${mdMatches.length} md= patterns in page source`);
    }
    
    // Add current page URL if it has md=
    if (window.location.href.includes('md=')) {
        urls.add(window.location.href);
        console.log("Added current page:", window.location.href);
    }
    
    const urlArray = Array.from(urls).sort();
    
    console.log(`\nβœ… Found ${urlArray.length} unique lesson URLs:`);
    urlArray.forEach((url, index) => {
        console.log(`${index + 1}. ${url}`);
    });
    
    if (urlArray.length === 0) {
        console.log("\n❌ No lesson URLs found!");
        console.log("πŸ’‘ Try running this from the main classroom navigation page");
        console.log("πŸ’‘ Or manually add URLs to the list below");
        
        // Add current URL as fallback
        urlArray.push(window.location.href);
    }
    
    // Create urls.txt file and download it
    const urlText = urlArray.join('\n');
    const blob = new Blob([urlText], {type: 'text/plain'});
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'urls.txt';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    
    console.log("\nπŸ“ Downloaded urls.txt with all found URLs");
    console.log("πŸ“ Next steps:");
    console.log("1. Check the downloaded urls.txt file");
    console.log("2. Add any missing URLs manually if needed");
    console.log("3. Use: wget --input-file=urls.txt [other options]");
    
    return urlArray;
}

// Run the extraction
extractAllLessonUrls();

step 2 - get the video URLs

OUT="skool_videos.csv"
echo "page_url,video_url" > "$OUT"

UA='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36'

while read -r url; do
  echo "🎬 $url"
  video_url=$(yt-dlp \
      --no-download \
      --cookies-from-browser 'chrome:Default' \
      --add-header 'Referer: https://www.skool.com' \
      --user-agent "$UA" \
      -g "$url" 2>/dev/null | head -n1)

  if [ -n "$video_url" ]; then
    u=${url//\"/\"\"}; v=${video_url//\"/\"\"}
    echo "\"$u\",\"$v\"" >> "$OUT"
  else
    echo "\"$url\",\"(no video found)\"" >> "$OUT"
  fi
done <<'EOF'
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=0430f1b55fa146099a333506c6adb7ac
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=07f532f5344e4e71931bc61a7012fc56
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=15a99e028f68448eb51bf3231193fa1e
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=2162014643b44955ac27e6a49a9bbfdb
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=241bb271979f4f048b3050afc6c3a6e7
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=2a7ea6f0f1ae44a1a652b875cdf56e3e
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=2f37246fdd4f41c2b583c32fae4c82c6
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=2fc1a4b69db44eb99d53836b89406e1a
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=305d21a71dc64c6fa160d01d5e1732f7
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=34bf2939e6244342ae5c1edbf3b66804
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=39006435e6994fafaf8d84bf2578fc13
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=3c00e02c347e4968a21dc06bc712a492
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=3c5a77d8b8e44d52a625fc15d3cbb097
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=5ac5eb70c433462d9707f682440e502a
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=6d0b52cf95754b3e8def92cd0e9ed515
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=6dae34fac53844ff9414ac111cd2a29d
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=771b8408d3e84121846821ee4edd2316
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=84a5700317ef438181803ead482559b9
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=97222e26586c4fe48e27718e6090afda
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=99b2e9902f8f4133b071783a793f0941
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=9e93db7167e2432fab1e3d5d9887a032
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=a3af94094d35474a969292647f3b67da
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=b1e5589513a841f9bea98e169bab1063
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=bd4248fdbba94a25b5771b20ffc4c575
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=bdaaccaf77bd40d48095292024e6884a
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=bdbbe71fdaa64c89955e56d7a5082c6c
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=c0e2fa30f36a49c797464af7038076ab
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=c736e4b079bc4c83a64dba0b9cc5888e
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=ca85b423a718445faa5ddc8994812600
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=d40c79de043b4e5bbf943891b4ef4a80
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=d499064ead6c4f2e940a7eaf2e373ce9
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=e109e6e50d7142149c7be3df20e5a11c
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=e1ef26ed69c149ecbb63452c5bd07888
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=f90b58948a3d4936857ff5e72e548437
https://www.skool.com/freedom-achievers/classroom/67977c4d?md=f982699aa2ee44b3b9508765081c8d4f
EOF

echo "βœ… Saved to $OUT"

Related

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