使用JavaScript备份QQ空间的留言板数据

内容转载自我的博客

1. 目标网站

此代码是专门为了备份本人的QQ空间留言板的数据而编写的,前提是自己在浏览器登录Qzone账号,且代码只能运行在此链接https://user.qzone.qq.com/123456789/infocenter,其中的123456789是用户本人的qq号码,另外用户要手动点击网页的留言板栏目,然后再运行代码。实现的功能是将每一层楼的留言数据按顺序保存

2. 保存浏览器调试窗口的变量到本地文件

编写以下代码,粘贴到控制台并回车

// 为标准console对象添加一个save函数
(function(console){
    console.save = function(data, filename){
        // 若data为空则提示用户
        if(!data) {
            console.error('Console.save: No data');
            return;
        }
        // 默认文件名
        if(!filename){
            filename = 'console.json';
        }
        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4);
        }
        var blob = new Blob([data], {type: 'text/json'}),
        e = document.createEvent('MouseEvents'),
        a = document.createElement('a');
        a.download = filename;
        a.href = window.URL.createObjectURL(blob);
        a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        a.dispatchEvent(e);
    }
})(console)

然后可以在控制台输入console.save(var_imgs, 'imgs.json')并回车,浏览器会自动弹出下载文件窗口,并将此变量内容以json格式保存到本地

3. 编写代码

此网站的数据如果需要备份,必须注册并登录账号
本代码假定已经登录账号的情况下,且用户已经输入链接https://user.qzone.qq.com/123456789/infocenter,其中的123456789是用户本人的qq号码,并手动点击网页的留言板栏目,用户需要自己查看留言板的总页数,将它写入变量comment_page_number,然后粘贴并运行代码即可

// 保证F12后的console处选中tgb(msgbcanvas.html)而不是top,否则会出错

// var comment_page_div = document.getElementsByClassName("mod_pagenav_count")[1].getElementsByTagName('a');
// var comment_page_number = parseInt(comment_page_div[comment_page_div.length-1].textContent);
// 留言的页数,将当前页面打开为留言的最新一页
var comment_page_number =77;
var comment_array = new Array();
// 为标准console对象添加一个save函数
(function(console){
    console.save = function(data, filename){
        if(!data) {
            console.error('Console.save: No data');
            return;
        }
        if(!filename){
            filename = 'console.json';
        }
        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4);
        }
        var blob = new Blob([data], {type: 'text/json'}),
        e = document.createEvent('MouseEvents'),
        a = document.createElement('a');
        a.download = filename;
        a.href = window.URL.createObjectURL(blob);
        a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        a.dispatchEvent(e);
    }
})(console)

// 解析回复部分
function parse_reply(ol_reply) {
    var result = [];
    if(ol_reply.textContent==''){
        return [];
    }
    var content, timestamp, source;
    for(var i=0;i<ol_reply.childElementCount;i++){
        li_reply = ol_reply.childNodes[i];
        info = li_reply.firstElementChild.lastElementChild;
        source = info.firstElementChild.firstElementChild.textContent;
        content = info.firstElementChild.textContent.substring(source.length+1);
        timestamp = info.lastElementChild.firstElementChild.textContent;
        result.push({'发送方':source, '发送内容':content, '时间':timestamp});
    }
    return result;
}

// 解析某条评论
function parse_comment(comment_item) {
    var div_inner = comment_item.firstElementChild.lastElementChild.firstElementChild.firstElementChild;
    var span_user = div_inner.childNodes[0].firstElementChild.firstElementChild.firstElementChild;
    var username = span_user.textContent;
    var userlink = span_user.href;
    var floor_index = div_inner.childNodes[0].childNodes[1].textContent;
    // 暂不支持图片及表情,这些内容会显示为''
    var content = div_inner.childNodes[2].firstElementChild.textContent;
    var div_reply = parse_reply(div_inner.childNodes[4].lastElementChild.childNodes[2]);
    var timestamp = div_inner.childNodes[2].lastElementChild.firstElementChild.textContent;
    var result = {
        '用户':username, '链接':userlink, '楼层':floor_index,
        '内容':content, '时间':timestamp, '回复':div_reply
    }
    comment_array.push(result);
    console.log(result);
}

// 解析某一页的结果
function parse_single() {
    var comments = document.getElementById("ulCommentList");
    for(var i=0;i<comments.childElementCount;i++){
        parse_comment(comments.childNodes[i]);
    }
}

function control_page(index) {
    if(index>=comment_page_number){
        console.save(comment_array, '评论.json');
        return;
    }
    // 解析当前页面
    parse_single();
    // -1表示上一页,1表示下一页
    QZBlog.Util.PageIndexManager.goPage(1);
    // QZBlog.Util.PageIndexManager.goDirectPage(77)
    index = index + 1;
    setTimeout(control_page, 5000, index);
}


setTimeout(control_page, 5000, 0);

/*
// 解析某条评论
function parse_comment_bk(comment_item) {
    var inner_item = comment_item.getElementsByClassName('inner')[0];
    var username = inner_item.getElementsByClassName('c_tx q_namecard')[0].textContent;
    var userlink = inner_item.getElementsByClassName('c_tx q_namecard')[0].href;
    var floor_index = inner_item.getElementsByClassName('c_tx3 floor')[0].textContent;
    // var mobile_cp = inner_item.getElementsByClassName('c_tx3 unline')[0].textContent;
    var content = inner_item.getElementsByTagName("table")[0].textContent;
    var timestamp = inner_item.getElementsByClassName('c_tx3 mode_post')[1].textContent;
    var result = {
        '用户':username, '链接':userlink, '楼层':floor_index,
        '内容':content, '时间':timestamp
    }
    comment_array.push(result);
    console.log(result);
}

// 解析某一页的结果
function parse_single_bk() {
    var comments = document.getElementById("ulCommentList").getElementsByTagName("li");
    for(var i=0;i<document.getElementById("ulCommentList").length;i++){
        parse_comment(comments[i]);
    }
}
*/

4. 备份完成

最后的json文件部分内容示例如下,只支持文字消息的备份

[
    {
        "用户": "张三",
        "链接": "http://user.qzone.qq.com/111222333",
        "楼层": "第310楼",
        "内容": "生日快乐",
        "时间": "2020-07-06 21:23",
        "回复": [
            {
                "发送方": "我",
                "发送内容": "谢谢",
                "时间": "2019-07-06 23:24"
            },
            {
                "发送方": "张三",
                "发送内容": "明天见",
                "时间": "2019-07-06 23:26"
            },
            {
                "发送方": "我",
                "发送内容": "哈哈,回见",
                "时间": "2019-07-06 23:30"
            }
        ]
    },
    {
        "用户": "李四",
        "链接": "http://user.qzone.qq.com/123412345",
        "楼层": "第309楼",
        "内容": "新年快乐",
        "时间": "2020-02-01 17:44",
        "回复": [
            {
                "发送方": "我",
                "发送内容": "谢谢,同乐",
                "时间": "2020-02-01 23:24"
            }
        ]
    },
    {
        "用户": "王五",
        "链接": "http://user.qzone.qq.com/666777888",
        "楼层": "第308楼",
        "内容": "加油!!!!",
        "时间": "2019-06-06 00:21",
        "回复": [
            {
                "发送方": "我",
                "发送内容": "共勉",
                "时间": "2019-06-06 17:05"
            }
        ]
    },
    // 以下内容省略
]

5. 后记

当我完成之后,发现github已经有整个QQ空间的备份工具了。。。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342