// ==UserScript== // @name Export All Useful Links // @name:zh-CN 导出网页中的全部有效链接 // @namespace xcl // @version 1.3 // @description:zh-CN 点击右下角导出图标,自动爬取全部有效链接并导出为excel表格 // @author xcl // @match *://*/* // @run-at document-end // @grant none // @description Get all links from a website. right-click -> tampermonkey -> "Get All Links". // @downloadURL none // ==/UserScript== // 格式化网址作为文件名 function formatFilename(url) { if (url.indexOf("http://") != -1) { url = url.replace('http://', '') } else { url = url.replace('https://', '') } var symbol = ['<', '>', '/', '\\', '|', ':', '*', '?', '#'] symbol.forEach(ch => { var reg = new RegExp("/" + ch + "/g") url = url.replace(reg, '_') }); return url } // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载 function sheet2blob(sheet, sheetName) { sheetName = sheetName || 'sheet1'; var workbook = { SheetNames: [sheetName], Sheets: {} }; workbook.Sheets[sheetName] = sheet; // 生成excel的配置项 var wopts = { bookType: 'xlsx', // 要生成的文件类型 bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性 type: 'binary' }; var wbout = XLSX.write(workbook, wopts); var blob = new Blob([s2ab(wbout)], { type: "application/octet-stream" }); // 字符串转ArrayBuffer function s2ab(s) { var buf = new ArrayBuffer(s.length); var view = new Uint8Array(buf); for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; return buf; } return blob; } function downloadExcel(aoa, filename) { var sheet = XLSX.utils.aoa_to_sheet(aoa); console.log("正在导出表格") const blob = sheet2blob(sheet, "Sheet1") const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = `${filename}.xlsx` document.body.appendChild(link) link.click() document.body.removeChild(link) } function make_list(results) { var data_list = []; let table = ""; results.forEach(result => { if (result.url != window.location.href && result.url != "" && !result.url.includes('javascript')) { table += ``; data_list.push([result.url, result.name]); } }); table += "
${result.url} ${result.name}
"; // window.open("").document.write(table); downloadExcel(data_list, formatFilename(window.location.href)) } function inIframe(doc, results) { if (doc == null) return results; console.log(doc) let urls = doc.querySelectorAll("a"); urls.forEach(url => { let link_name = url.textContent.replace(/\t|\s+/g, "").trim(); let link = url.href; results.push({ name: link_name, url: link }); }); var iframes = doc.getElementsByTagName("iframe") for (var i = 0; i < iframes.length; i++) { inIframe(iframes[i].contentDocument, results) } return results } async function writeFile(fileHandle, contents) { // Create a FileSystemWritableFileStream to write to. const writable = await fileHandle.createWritable(); // Write the contents of the file to the stream. await writable.write(contents); // Close the file and write the contents to disk. await writable.close(); } function get_links() { let results = []; results = inIframe(document, results) make_list(results); } (function () { "use strict"; console.log("正在执行") let script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script.src = "https://cdn.bootcdn.net/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"; document.documentElement.appendChild(script); var toTopBtn = document.createElement('button') toTopBtn.innerHTML = "导出" toTopBtn.className = "a-b-c-d-toTop" let fileHandle; toTopBtn.addEventListener('click', async(e) => { fileHandle = await window.showOpenFilePicker(); console.log(fileHandle); const file = await fileHandle[0].getFile(); let contents = await file.text(); console.log(contents) let contentList = contents.split('\n') console.log(contentList) for(let i = 0; i < contentList.length; i++) { if(contentList[i] == window.location.href) { alert("提示:该网站已经爬取过!") return } } contents += (window.location.href+'\n') console.log(contents) get_links() writeFile(fileHandle[0], contents) }) var body = document.body var style = document.createElement('style') style.id = "a-b-c-d-style" var css = `.a-b-c-d-toTop{ position: fixed; bottom: 10%; right: 5%; width: 50px; height: 50px; border-radius: 50%; font-size: 15px; z-index: 999; cursor: pointer; font-size: 12px; overflow: hidden; background: blue }` if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } body.appendChild(toTopBtn) body.appendChild(style) })();