您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
抓取课程信息并导出CSV,无需发送后端
// ==UserScript== // @name 幕客网课程抓取工具(导出CSV本地下载) // @namespace http://tampermonkey.net/ // @version 2.51 // @description 抓取课程信息并导出CSV,无需发送后端 // @match https://coding.imooc.com/* // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; const allCourses = []; function showLoading() { const loading = document.createElement('div'); loading.id = 'imooc-loading-overlay'; loading.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.4); display: flex; justify-content: center; align-items: center; z-index: 9998; font-size: 20px; color: white; font-weight: bold; `; loading.innerHTML = '⏳ 正在抓取课程数据,请稍候...'; document.body.appendChild(loading); } function hideLoading() { const loading = document.getElementById('imooc-loading-overlay'); if (loading) document.body.removeChild(loading); } function getTotalPages() { const pageLinks = document.querySelectorAll('.page a[href*="page="]'); const pages = Array.from(pageLinks) .map(a => { const match = a.href.match(/page=(\d+)/); return match ? parseInt(match[1]) : null; }) .filter(n => n !== null); return pages.length ? Math.max(...pages) : 1; } function getBaseUrlAndParam() { const url = new URL(window.location.href); const base = url.origin + url.pathname; const searchParams = new URLSearchParams(url.search); searchParams.delete('page'); const paramStr = searchParams.toString(); return { baseUrl: base, paramPrefix: paramStr ? `${paramStr}&` : '' }; } function parseHTML(htmlText) { const parser = new DOMParser(); const doc = parser.parseFromString(htmlText, 'text/html'); const cards = doc.querySelectorAll('li.course-card'); const pageCourses = []; cards.forEach(card => { const name = card.getAttribute('data-name'); const price = card.getAttribute('data-price') + '元'; const numbersText = card.querySelector('p.one .numbers')?.innerText || ''; const [level, applyRaw] = numbersText.split('·').map(s => s.trim()); const apply = applyRaw?.replace('人报名', '') || ''; const imgDiv = card.querySelector('.img'); let image = ''; if (imgDiv) { const style = imgDiv.getAttribute('style') || ''; const match = style.match(/url\((.*?)\)/); if (match && match[1]) { image = match[1].startsWith('//') ? 'https:' + match[1] : match[1]; } } pageCourses.push({ name, level, apply, price, image }); }); return pageCourses; } function exportCSV(dataArray, filename = 'imooc_courses.csv') { const headers = ['课程名称', '等级', '报名人数', '价格', '图片地址']; const rows = dataArray.map(d => [d.name, d.level, d.apply, d.price, d.image]); const csvContent = [headers, ...rows] .map(row => row.map(item => `"${String(item).replace(/"/g, '""')}"`).join(',')) .join('\n'); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = filename; link.click(); } async function fetchAllPages() { allCourses.length = 0; showLoading(); const totalPages = getTotalPages(); const { baseUrl, paramPrefix } = getBaseUrlAndParam(); for (let page = 1; page <= totalPages; page++) { const url = `${baseUrl}?${paramPrefix}page=${page}`; console.log(`📄 抓取第 ${page} 页:${url}`); try { const res = await fetch(url, { credentials: 'include' }); const html = await res.text(); const courses = parseHTML(html); allCourses.push(...courses); } catch (err) { console.error(`❌ 第 ${page} 页请求失败:`, err); break; } } console.log('✅ 抓取完成,共', allCourses.length, '条课程'); hideLoading(); if (allCourses.length > 0) { exportCSV(allCourses); } else { alert('未抓取到任何课程信息。'); } } function addGrabButton() { const btn = document.createElement('button'); btn.textContent = '📦 导出课程CSV'; btn.style.cssText = ` position: fixed; top: 100px; right: 20px; z-index: 9999; background-color: #28a745; color: white; padding: 10px 16px; font-size: 14px; border: none; border-radius: 6px; box-shadow: 0 0 6px rgba(0,0,0,0.2); cursor: pointer; `; btn.onclick = fetchAllPages; document.body.appendChild(btn); } window.addEventListener('load', () => { setTimeout(addGrabButton, 1000); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址