Monknow新标签页数据导出

Monknow是一款浏览器扩展,用作新标签页。但是官方没有提供数据导出的功能,导致我们收藏的很多网页没办法进行数据迁徙,这里我们自己动手通过js脚本导出数据。

使用说明(在Edge浏览器上测试通过):

  • 打开MonKonw新标签页 :确保您看到的是MonKonw的标签页界面(需要登录自己的账户)
  • 按F12打开开发者工具 :进入浏览器的调试模式
  • 切换到控制台 :在开发者工具中找到并点击"控制台(Console)"选项卡
  • 复制以下脚本 :将完整的脚本复制到剪贴板
  • 粘贴并执行 :将脚本粘贴到控制台中,然后按Enter键执行
javascript 复制代码
// MonKonw Chrome 扩展数据导出脚本
(function() {
    console.log('=== MonKonw Chrome 扩展数据导出 ===');
    console.log('执行时间:', new Date().toLocaleString());
    console.log('当前页面:', window.location.href);
    
    // 检查是否在扩展页面中
    if (!window.location.href.startsWith('chrome-extension://')) {
        console.error('错误:请在 MonKonw 扩展页面中执行此脚本!');
        console.error('请打开新标签页,确保是 MonKonw 标签页,然后重新执行脚本。');
        return;
    }
    
    // 1. 检查 chrome.storage API
    console.log('\n1. 检查 Chrome 扩展存储 API...');
    if (typeof chrome !== 'undefined' && chrome.storage) {
        console.log('Chrome 扩展存储 API 可用');
        
        // 读取所有存储数据
        function readAllStorage() {
            return new Promise((resolve) => {
                const allData = {};
                
                // 读取 local 存储
                chrome.storage.local.get(null, (localData) => {
                    allData.local = localData;
                    
                    // 读取 sync 存储
                    chrome.storage.sync.get(null, (syncData) => {
                        allData.sync = syncData;
                        
                        // 读取 managed 存储(如果有)
                        chrome.storage.managed.get(null, (managedData) => {
                            allData.managed = managedData;
                            resolve(allData);
                        });
                    });
                });
            });
        }
        
        // 执行数据读取
        readAllStorage().then((storageData) => {
            console.log('\n2. 存储数据读取完成:');
            console.log('local 存储项数量:', Object.keys(storageData.local).length);
            console.log('sync 存储项数量:', Object.keys(storageData.sync).length);
            console.log('managed 存储项数量:', Object.keys(storageData.managed).length);
            
            // 显示存储数据的键名
            console.log('\n存储数据键名:');
            console.log('local 存储:', Object.keys(storageData.local));
            console.log('sync 存储:', Object.keys(storageData.sync));
            
            // 3. 检查页面元素,寻找收藏数据
            console.log('\n3. 检查页面元素...');
            
            // 查找所有可能包含收藏的元素
            const possibleSelectors = [
                '.site-item', '.bookmark-item', '.fav-item', '.website-item',
                '.card', '.item', '.tile', '.box',
                '[data-site]', '[data-url]', '[data-bookmark]'
            ];
            
            let allItems = [];
            
            possibleSelectors.forEach(selector => {
                const elements = document.querySelectorAll(selector);
                if (elements.length > 0) {
                    console.log(`发现 ${elements.length} 个 ${selector} 元素`);
                    
                    elements.forEach(el => {
                        try {
                            // 尝试获取标题和URL
                            let title = el.textContent.trim() || el.getAttribute('title') || '无标题';
                            let url = '';
                            
                            // 检查是否有直接链接
                            if (el.href) {
                                url = el.href;
                            } 
                            // 检查 data 属性
                            else if (el.dataset.url) {
                                url = el.dataset.url;
                            } 
                            else if (el.getAttribute('data-url')) {
                                url = el.getAttribute('data-url');
                            }
                            // 检查子元素中的链接
                            else {
                                const linkEl = el.querySelector('a[href]');
                                if (linkEl) {
                                    url = linkEl.href;
                                    title = linkEl.textContent.trim() || title;
                                }
                            }
                            
                            if (url && url.startsWith('http')) {
                                allItems.push({ title, url, selector });
                            }
                        } catch (e) {
                            console.error('解析元素失败:', e);
                        }
                    });
                }
            });
            
            // 去重
            const uniqueItems = [...new Map(allItems.map(item => [item.url, item])).values()];
            console.log(`\n找到 ${uniqueItems.length} 个唯一的外部链接`);
            
            // 4. 检查扩展的 indexedDB 数据库
            console.log('\n4. 检查扩展的 IndexedDB 数据库...');
            
            // 扩展的 indexedDB 数据库名通常包含扩展 ID
            const extensionId = window.location.hostname;
            console.log('扩展 ID:', extensionId);
            
            if (window.indexedDB) {
                indexedDB.databases().then(databases => {
                    console.log('发现 IndexedDB 数据库:', databases);
                    
                    // 尝试读取与扩展相关的数据库
                    const extensionDatabases = databases.filter(db => 
                        db.name && (db.name.includes(extensionId) || db.name.includes('monknow'))
                    );
                    
                    console.log('与扩展相关的数据库:', extensionDatabases);
                    
                    // 5. 下载所有数据
                    console.log('\n5. 准备下载所有数据...');
                    
                    const exportData = {
                        timestamp: new Date().toISOString(),
                        extensionId: extensionId,
                        pageUrl: window.location.href,
                        storageData: storageData,
                        pageItems: uniqueItems,
                        indexedDBDatabases: databases
                    };
                    
                    // 下载数据
                    const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = 'monknow-extension-data.json';
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                    
                    console.log('\n=== 导出完成 ===');
                    console.log('已下载扩展数据文件: monknow-extension-data.json');
                    console.log('\n数据文件包含:');
                    console.log('- Chrome 扩展存储数据 (local 和 sync)');
                    console.log('- 页面上的所有外部链接');
                    console.log('- 扩展相关的 IndexedDB 数据库信息');
                    
                    // 尝试提取收藏数据
                    console.log('\n6. 尝试提取收藏数据...');
                    
                    // 检查存储数据中是否有收藏相关的键
                    const possibleKeys = ['sites', 'bookmarks', 'favorites', 'websites', 'urls', 'data'];
                    let foundBookmarks = [];
                    
                    // 检查存储数据
                    Object.values(storageData).forEach(storage => {
                        Object.entries(storage).forEach(([key, value]) => {
                            possibleKeys.forEach(possibleKey => {
                                if (key.toLowerCase().includes(possibleKey) || 
                                    (typeof value === 'object' && value !== null && 
                                     (Array.isArray(value) || Object.values(value).some(v => 
                                         typeof v === 'object' && v !== null && (v.url || v.link))))
                                ) {
                                    console.log(`\n发现可能包含收藏的数据: ${key}`);
                                    console.log('数据类型:', typeof value);
                                    
                                    // 尝试解析为收藏
                                    try {
                                        if (Array.isArray(value)) {
                                            const bookmarks = value.filter(item => 
                                                item && typeof item === 'object' && (item.url || item.link)
                                            ).map(item => ({
                                                title: item.title || item.name || '无标题',
                                                url: item.url || item.link,
                                                from: `storage.${key}`
                                            }));
                                            foundBookmarks.push(...bookmarks);
                                        } else if (typeof value === 'object') {
                                            // 处理对象类型
                                            Object.values(value).forEach(item => {
                                                if (item && typeof item === 'object' && (item.url || item.link)) {
                                                    foundBookmarks.push({
                                                        title: item.title || item.name || '无标题',
                                                        url: item.url || item.link,
                                                        from: `storage.${key}`
                                                    });
                                                }
                                            });
                                        }
                                    } catch (e) {
                                        console.error('解析收藏数据失败:', e);
                                    }
                                }
                            });
                        });
                    });
                    
                    // 合并页面数据和存储数据
                    const allBookmarks = [...foundBookmarks, ...uniqueItems];
                    const finalBookmarks = [...new Map(allBookmarks.map(b => [b.url, b])).values()];
                    
                    console.log(`\n共提取到 ${finalBookmarks.length} 个收藏项`);
                    
                    // 如果有收藏项,下载单独的收藏文件
                    if (finalBookmarks.length > 0) {
                        console.log('\n7. 下载收藏数据...');
                        
                        const bookmarksData = {
                            timestamp: new Date().toISOString(),
                            total: finalBookmarks.length,
                            bookmarks: finalBookmarks
                        };
                        
                        const bookmarksBlob = new Blob([JSON.stringify(bookmarksData, null, 2)], { type: 'application/json' });
                        const bookmarksUrl = URL.createObjectURL(bookmarksBlob);
                        const bookmarksA = document.createElement('a');
                        bookmarksA.href = bookmarksUrl;
                        bookmarksA.download = 'monknow-bookmarks.json';
                        document.body.appendChild(bookmarksA);
                        bookmarksA.click();
                        document.body.removeChild(bookmarksA);
                        URL.revokeObjectURL(bookmarksUrl);
                        
                        console.log('已下载收藏文件: monknow-bookmarks.json');
                        console.log('收藏项列表:');
                        finalBookmarks.forEach((bookmark, index) => {
                            console.log(`${index + 1}. ${bookmark.title} - ${bookmark.url}`);
                        });
                    }
                    
                    console.log('\n=== 导出总结 ===');
                    console.log(`总收藏项: ${finalBookmarks.length}`);
                    console.log('来自存储数据:', foundBookmarks.length);
                    console.log('来自页面元素:', uniqueItems.length);
                    console.log('\n请查看下载的文件,获取完整的导出数据。');
                }).catch(error => {
                    console.error('检查 IndexedDB 失败:', error);
                });
            } else {
                console.error('浏览器不支持 IndexedDB');
            }
        });
    } else {
        console.error('Chrome 扩展存储 API 不可用');
        console.error('请确保在 MonKonw 扩展页面中执行此脚本,并且扩展具有 storage 权限。');
    }
})();

脚本工作原理

这个脚本专门针对Chrome扩展设计,使用了Chrome扩展特有的 chrome.storage API,这是Chrome扩展存储数据的主要方式(Edge浏览器也可)。脚本会:

  1. 检查是否在MonKonw扩展页面中执行
  2. 使用 chrome.storage.local 和 chrome.storage.sync 读取扩展存储的所有数据
  3. 检查页面上的所有元素,寻找收藏的网页链接
  4. 检查扩展的IndexedDB数据库
  5. 下载包含所有数据的JSON文件
  6. 尝试从存储数据中提取收藏项,并单独下载一个收藏文件
  7. 显示详细的导出总结
相关推荐
小妖6662 小时前
力扣(LeetCode)- 93. 复原 IP 地址(JavaScript)
javascript·tcp/ip·leetcode
郑州光合科技余经理3 小时前
实战:攻克海外版同城生活服务平台开发五大挑战
java·开发语言·javascript·数据库·git·php·生活
Yanni4Night3 小时前
JavaScript打包器大奖赛:谁是构建速度之王? 🚀
前端·javascript
SakuraOnTheWay3 小时前
解构 JavaScript 迭代器:一行代码引发的性能思考
javascript·性能优化
默海笑3 小时前
VUE后台管理系统:项目架构之搭建Layout架构解决方案与实现
前端·javascript·vue.js
csdn_aspnet3 小时前
C# 电子签名及文档存储
javascript·c#
1024肥宅4 小时前
现代 JavaScript 特性:ES6+ 新特性深度解析与实践
前端·javascript·面试
BD_Marathon5 小时前
Vue3_工程文件之间的关系
前端·javascript·vue.js
weibkreuz5 小时前
模块与组件、模块化与组件化的理解@3
开发语言·前端·javascript