【问题标题】:How to append json with no duplicating (including CasperJS code)?如何在不重复的情况下附加 json(包括 CasperJS 代码)?
【发布时间】:2015-09-05 17:17:48
【问题描述】:

我正在使用 CasperJS 来解析网页的内部文本并保存到 json 文件。

这是我的代码,我会在下面显示结果(我遇到的问题)!

var words = [];
var casper = require('casper').create();
var x = require('casper').selectXPath;
var fs = require('fs');

function getWords() {
    var words = document.querySelectorAll('span.inner_tit');
    return Array.prototype.map.call(words, function(e) {
        return e.innerHTML;
    });
}

function createFinal(wordArray) {
    var out = [];
    wordArray.forEach(function(word) {
        out.push({"type": "river", "name": word, "spell": word.length});
    });
    return out;
}    

casper.start('http://dic.daum.net/index.do?dic=kor');


casper.thenClick(x('//*[@id="searchSubmit"]'), function(){
    console.log('searching');
});

casper.wait(2000, function() {
    casper.then(function() {
        words = this.evaluate(getWords);
    });
});

casper.wait(3000, function() {
    casper.thenClick(x('//*[@id="mArticle"]/div[2]/a[2]'), function (){
        words = words.concat(this.evaluate(getWords));
    });
});

casper.run(function() {
    var my_object = { "my_initial_words": createFinal(words)};
    this.echo(JSON.stringify(my_object, null, '\t'))
    var result = JSON.stringify(my_object, null, '\t')
    fs.write('myresults.json', result, 'a');
    this.exit();

});

这段代码的问题是,当我有这样的json代码时,

{
    "my_initial_words": [
        {
            "type": "river",
            "name": "apple",
            "spell": "5"
        },
        {
            "type": "river",
            "name": "banana",
            "spell": "6"
        }   
    ]
}

我的代码附加了所有内容,包括像这样的 json 数组的名称!

{
    "my_initial_words": [
        {
            "type": "river",
            "name": "apple",
            "spell": "5"
        },
        {
            "type": "river",
            "name": "banana",
            "spell": "6"
        }   
    ]
}  {
    "my_initial_words": [
        {
            "type": "river",
            "name": "apple",
            "spell": "5"
        },
        {
            "type": "river",
            "name": "banana",
            "spell": "6"
        }   
    ]
}

所以.. 我不需要添加所有内容,只想添加这些元素! (没有“我的_initial_words:[]”)

{"type": "river",   "name": "apple","spell": "5"},
{"type": "river",   "name": "banana","spell": "6"}  

【问题讨论】:

    标签: javascript json casperjs


    【解决方案1】:

    更新文件中的对象

    JSON 的定义方式是,您不能将对象附加到现有对象并期望从中获取有效的 JSON。不过你可以

    1. 读取之前序列化的JSON字符串,
    2. 解析成一个对象,
    3. 将新值附加到数组中,
    4. 再次序列化对象并
    5. 用它完全覆盖现有文件。

    例如这样:

    var previousDataString = fs.read('myresults.json');
    var previousData = JSON.parse(previousDataString);
    previousData["my_initial_words"] = previousData["my_initial_words"].concat(createFinal(words));
    var newData = JSON.stringify(previousData, null, '\t')
    fs.write('myresults.json', newData, 'w');
    

    将块写入文件

    如果您仍想将数据文件编写为单独的 JSON 块,那么您可以这样做:

    // Combine all items into a single string
    var newItemsString = createFinal(words).reduce(function(combinedString, currentItem){
        return combinedString + JSON.stringify(currentItem) + "\n";
    }, "")
    // append new items to previous items
    fs.write('myresults.json', newItemsString, 'a');
    

    每个项目(单词的对象)都写在一行上。当您在其他进程中读取文件时,您可以使用 readLine() 等函数一次仅读取一项。

    修复过早退出

    您还必须记住退出 CasperJS 的方式。如果您向casper.run() 提供回调,则需要显式调用casper.exit() 才能退出进程。问题是你做得太早了:

    this.echo(JSON.stringify(previousData, null, '\t')).exit();
    //                                                 ^^^^^^^ calling exit
    var newData = JSON.stringify(previousData, null, '\t'); // not executed
    fs.write('myscript.json', newData, 'w');  // not executed
    

    要么你需要将退出放在回调的末尾:

    this.echo(JSON.stringify(previousData, null, '\t'));
    var newData = JSON.stringify(previousData, null, '\t');
    fs.write('myscript.json', newData, 'w');
    this.exit();
    

    或者不要将最终代码放入casper.then() 而不是casper.run()

    casper.then(function() {
        var previousDataString = fs.read('myscript.json');
        var previousData = JSON.parse(previousDataString);
        previousData["my_initial_words"] = previousData["my_initial_words"].concat(createFinal(words));
        this.echo(JSON.stringify(previousData, null, '\t'));
        var newData = JSON.stringify(previousData, null, '\t')
        fs.write('myscript.json', newData, 'w');
    });
    casper.run();
    

    【讨论】:

    • 能否请您再读一次我的问题并编辑我的问题!
    • 是的,因为您在写入文件之前要退出 CasperJS。我已经更新了我的答案并回复了你的问题。
    • 对不起,但没有改变...我尝试添加“this.exit();”(也编辑我的代码)我的爬取数据(我通过“console.日志”未添加到我的 json 文件中..
    • 您需要删除this.echo()末尾的第一个.exit()
    • 我删除了但是...我尝试了最后一个...但是没有变化ㅠㅠ
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    相关资源
    最近更新 更多