如何附加 json 而不重复(包括 CasperJS 代码)?

How to append json with no duplicating (including CasperJS code)?

我正在使用 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"
        }   
    ]
}

所以..我不需要全部添加但只想添加这些元素! (没有 "my _initial_words: []")

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

正在更新文件中的对象

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();