Chapter 14 JSON与CSV

json和csv是我们经常打交道的两种数据格式,girlfriend提供了内置插件对它们进行了读写支持。

JSON

读取不同格式的json文件

json格式的用途五花八门,有时候用来做配置文件,有时候用来做序列化。因为用途广泛,所以表现形式往往很多,girlfriend提供了read_json插件来作为读取json的工具,read_json可以支持本地文件和从web地址读取两种方式,同时它还支持许多常见的json表现形式。

按行读取

如果你的json文件是一行一个对象的形式,比如:

{"id": 1, "name": "Sam", "gender": "male"}
{"id": 2, "name": "Jack", "gender": "female"}
{"id": 3, "name": "James", "gender": "male"}
...

这种形式就可以使用按行读取的方式进行操作:

from girlfriend.plugin.json import JSONR

...

Job(
    name="read_json",
    args=[
        JSONR(
            path="jsonfile.json",
            style="line",
        ),
    ]
)

或者

from girlfriend.plugin.json import JSONR

...

Job(
    name="read_json",
    args=[
        JSONR(
            path="http://www.hehe.com/jsonfile.json",
            style="line",
        ),
    ]
)

read_json插件接受一组JSONR对象作为参数,每个JSONR代表了一个要解析的JSON文件或URL地址,style表示json的形式,line表示每行都是一个json对象,解析后的结果为一个list,其中的元素就是每行解析后的字典对象。

如果你不想要字典对象,而是想包装成为自定义的对象,那么你可以指定record_handler参数,该参数接受一个函数,在该函数中将字典转换为目标对象后返回即可。

如果你想过滤掉其中的一些记录不加入到最终的分析结果,那么可以使用record_filter,比如,只保留男性:

Job(
    name="read_json",
    args=[
        JSONR(
            path="http://www.hehe.com/jsonfile.json",
            style="line",
            record_filter=lambda record: record["gender"] == "male",
            record_handler=mapper
        ),
    ]
)

当你要处理的json数据非常的庞大时,按行解析是最好的方式,因为这种解析方式不会将整个json数据加载到内存,你可以筛选整理出自己所需要的。其它的文件格式则不保证这一点。

按块读取

这种情况通常用于配置文件,为了美观,我们会将一个json对象散布到多行,比如:

# id 1
{
    "id": 1,
    "name": {
        "first": "Sam",
        "last": "Chi"
    }
}

# id 2
{
    "id": 2,
    "name": {
        "first": "Bill",
        "last": "Gates",
    }
}

通过将style参数设置为block可以支持这种json文件格式,read_json会去尝试匹配一个最完整的json块作为一条记录。中间无关的字符串如"# id 1 # id 2"也会被自动忽略。

按数组读取

如果你的json文件是一个数组,那么通过将style设置成array可以使得数组中每个元素作为一条记录来被处理。

[
    {
        "id": 1,
        "name": {
            "first": "Sam",
            "last": "Chi"
        }
    },
    {
        "id": 2,
        "name": {
            "first": "Bill",
            "last": "Gates",
        }
    }
]

提取属性

如果你要处理的部分是json对象中的某个属性,那么你可以将style指定为extract:property_name。

{
    "id": 1,
    "name": "SamChi",
    "fav_books": {
        "total": 2,
        "books": [
            {
                "title": u"白夜行",
                "author": u"东野圭吾"
            },
            {
                "title": u"陆小凤传奇"
                "author": u"古龙"
            }
        ]
    }
}

如果我们只是要分析最内层的books这个列表,那么只需要将style指定为extract:fav_books.books即可。

按不同格式写入JSON文件

使用write_json插件可以将上下文中的对象以数组、json对象或者按行的方式去写入。

from girlfriend.plugin.json import JSONW

...

Job(
    name="write_json",
    args=[
        JSONW(
            path="输出文件路径,如果指定了variable,那么该参数可以不指定",
            style="line", # 还可以是object或者array
            object="要写入的对象或者上下文变量名",
            variable="将json序列化结果同时保存到上下文指定变量。"
        )
    ]
)

results matching ""

    No results matching ""