// ==UserScript== // @name UCAS讲座信息抓取 // @namespace http://tampermonkey.net/ // @version 1.1 // @description 抓取讲座信息并生成JSON到剪贴板,可从页面底部的附加面板上传至google calendar // @match https://xkcts.ucas.ac.cn:8443/subject/lecture // @match https://xkcts.ucas.ac.cn:8443/subject/humanityLecture // @grant GM_getValue // @license GPLv3 // @downloadURL https://update.greasyfork.icu/scripts/515800/UCAS%E8%AE%B2%E5%BA%A7%E4%BF%A1%E6%81%AF%E6%8A%93%E5%8F%96.user.js // @updateURL https://update.greasyfork.icu/scripts/515800/UCAS%E8%AE%B2%E5%BA%A7%E4%BF%A1%E6%81%AF%E6%8A%93%E5%8F%96.meta.js // ==/UserScript== (function() { 'use strict'; function assignIgnoringUndefined(target, ...sources) { sources.forEach(source => { Object.keys(source).forEach(key => { if (source[key] !== undefined) { target[key] = source[key]; } }); }); return target; } async function fetchDetails(url) { const response = await fetch(url); const text = await response.text(); const parser = new DOMParser(); const doc = parser.parseFromString(text, 'text/html'); // 根据实际情况调整选择器 const detailsTable = doc.querySelector('table'); // 选择第一个表格 let details = {}; if (detailsTable) { const rows = detailsTable.querySelectorAll('tr'); rows.forEach((row,index) => { // const cells = Array.from(row.querySelectorAll('td')); const plain = row.innerText; const regex = { startTime: /.+开始时间:([^\n]+)/, endTime: /.+结束时间:([^\n]+)/, mainVenue: /.+主会场地点:([^\n]+)/, }; // 提取字段 const extractedFields = { startTime: plain.match(regex.startTime)?.[1]?.trim(), endTime: plain.match(regex.endTime)?.[1]?.trim(), mainVenue: plain.match(regex.mainVenue)?.[1]?.trim(), }; if (plain.includes("讲座介绍")) { extractedFields.introduction = rows[index + 1]?.querySelector('td')?.textContent.trim(); } assignIgnoringUndefined(details,extractedFields); }); } console.log(details); return details; } function downloadFile(content, fileName) { const blob = new Blob([content], { type: 'text/csv' }); const url = URL.createObjectURL(blob); GM_download({ url: url, name: fileName, saveAs: true }); } async function scrapeTable() { const rows = Array.from(document.querySelectorAll('table tbody tr')); const data = []; for (const row of rows) { const cells = row.querySelectorAll('td'); const name = cells[0].innerText; const time = cells[2].innerText; const detailLink = cells[6].querySelector('a').href; console.log('detaill in',detailLink); const details = await fetchDetails(detailLink); data.push({ name: name, time: time, details: details }); } // const csvContent = '讲座名称,讲座时间,详情\n' + data.map(item => `${item.name},${item.time},"${item.details.replace(/"/g, '""')}"`).join('\n'); // downloadFile(csvContent, 'lectures.csv'); const jsonstr = JSON.stringify(data); const talksToUpload = jsonstr; console.log(jsonstr); navigator.clipboard.writeText(jsonstr).then(() => { console.log('数据已复制到剪贴板'); // 打开 t.html // window.open('http://localhost:1145/gcalendarSyncLectures.html', '_blank'); // 创建 iframe 元素 const iframe = document.createElement('iframe'); iframe.style.width = '100%'; // 设置宽度 iframe.style.height = '300px'; // 设置高度 iframe.style.border = '1px solid black'; // 设置边框 iframe.style.position = 'fixed'; // 固定位置 iframe.style.bottom = '10px'; // 距底部 10px iframe.style.left = '10px'; // 距左边 10px iframe.style.zIndex = '2000'; // 确保在其他元素之上 iframe.style.background = "white"; const CLIENT_ID = GM_getValue('CLIENT_ID',''); const API_KEY = GM_getValue('API_KEY'); console.log('client',CLIENT_ID,'api',API_KEY); // 设定 iframe 的内容 const iframeContent = ` Google Calendar API Quickstart

Google Calendar API Quickstart



    

    
    
    
  

            `;

            // 将 iframe 添加到页面中
            document.body.appendChild(iframe);
            // 写入内容
            const doc = iframe.contentDocument || iframe.contentWindow.document;
            console.log(iframe);
            console.log(iframeContent);
            console.log(iframe.contentDocument);
            // doc.open();
            doc.write(iframeContent);
            doc.close();

            const toggleAction = ()=>{
              console.log('toggle pannel',iframe.style.visibility);
              iframe.style.visibility=iframe.style.visibility=='hidden'?'visible':'hidden';
            }
            const toggle = document.createElement('button');
            toggle.innerText = 'Toggle Panel';
            toggle.style.position = 'fixed';
            toggle.style.bottom = '50px';
            toggle.style.right = '10px';
            toggle.style.zIndex = 2001;
            toggle.onclick = toggleAction;
            document.body.appendChild(toggle)

        }).catch(err => {
            console.error('复制失败:', err);
        });
    }

    const button = document.createElement('button');
    button.innerText = '抓取讲座信息';
    button.style.position = 'fixed';
    button.style.bottom = '10px';
    button.style.right = '10px';
    button.style.zIndex = 2001;
    button.onclick = scrapeTable;

    document.body.appendChild(button);
})();