5

yajl-py で GitHub アーカイブ ファイルを解析しようとしています。ファイルの基本的な形式は JSON オブジェクトのストリームであると考えているため、ファイル自体は有効な JSON ではありませんが、有効なオブジェクトが含まれています。

yajl-pyこれをテストするために、サンプル パーサー ( https://github.com/pykler/yajl-py/blob/master/examples/yajl_py_example.pyから)をインストールして使用し、ファイルの解析を試みました。

python yajl_py_example.py < 2012-03-12-0.json

2012-03-12-0.json、解凍された GitHub アーカイブ ファイルの 1 つです。

この種のことは、Ruby での参照実装から機能するはずです。Python パッケージは JSON ストリームを処理しませんか?

ちなみに、ここに私が得るエラーがあります:

yajl.yajl_common.YajlError: parse error: trailing garbage
          9478bbc3","type":"PushEvent"}{"repository":{"url":"https://g
                     (right here) ------^
4

4 に答える 4

4

データを読み取るには、ストリーム パーサーを使用する必要があります。Yajl はストリーム解析をサポートしており、ファイル/ストリームから一度に 1 つのオブジェクトを読み取ることができます。そうは言っても、Python には Yajl の有効なバインディングがあるようには見えません。

py-yajl がiterloadコメントアウトしましたが、理由は不明です: https://github.com/rtyler/py-yajl/commit/a618f66005e9798af848c15d9aa35c60331e6687#L1R264

Python ソリューションではありませんが、Ruby バインディングを使用してデータを読み取り、必要な形式で出力できます。

# gem install yajl-ruby

「open-uri」が必要
「zlib」が必要
「yajl」が必要

gz = オープン ('http://data.githubarchive.org/2012-03-11-12.json.gz')
js = Zlib::GzipReader.new(gz).read

Yajl::Parser.parse(js) do |イベント|
  印刷イベント
終わり
于 2012-05-04T18:09:01.477 に答える
1

これが回答されたことは知っていますが、次のアプローチを好み、パッケージを使用しません。何らかの理由で github ディクショナリは 1 行にあるため、1 行に 1 つのディクショナリを想定することはできません。これは次のようになります。

{"json-key":"json-val", "sub-dict":{"sub-key":"sub-val"}}{"json-key2":"json-val2", "sub-dict2":{"sub-key2":"sub-val2"}}

一度に 1 つの辞書を取得する関数を作成することにしました。json を文字列として返します。

def read_next_dictionary(f):
    depth = 0
    json_str = ""
    while True:
        c = f.read(1)
        if not c:
            break #EOF
        json_str += str(c)
        if c == '{':
            depth += 1
        elif c == '}':
            depth -= 1

        if depth == 0:
            break

    return json_str

この関数を使用して、while ループで Github アーカイブをループ処理しました。

arr_of_dicts = []
f = open(file_path)
while True:
    json_as_str = read_next_dictionary(f)
    try:
        json_dict = json.loads(json_as_str)
        arr_of_dicts.append(json_dict)
    except: 
        break # exception on loading json to end loop

pprint.pprint(arr_of_dicts)

これは、次のデータセットの投稿で機能します: http://www.githubarchive.org/ (gunzip の後)

于 2014-06-08T04:06:14.770 に答える
1

allow_multiple_valuesこの例では、パーサーでフラグを有効にする必要があるため、Yajl の追加機能を有効にしません。ファイルを解析するために基本的な例を変更する必要があるのは次のとおりです。

--- a/examples/yajl_py_example.py
+++ b/examples/yajl_py_example.py
@@ -37,6 +37,7 @@ class ContentHandler(YajlContentHandler):

 def main(args):
     parser = YajlParser(ContentHandler())
+    parser.allow_multiple_values = True
     if args:
         for fn in args:
             f = open(fn)

Yajl-Py は yajl の薄いラッパーなので、Yajl が提供するすべての機能を使用できます。以下は、yajl が提供する、有効にできるすべてのフラグです。

yajl_allow_comments
yajl_dont_validate_strings
yajl_allow_trailing_garbage
yajl_allow_multiple_values
yajl_allow_partial_values

これらを yajl-py でオンにするには、次のようにします。

parser = YajlParser(ContentHandler())
# enabling these features, note that to make it more pythonic, the prefix `yajl_` was removed
parser.allow_comments = True
parser.dont_validate_strings = True
parser.allow_trailing_garbage = True
parser.allow_multiple_values = True
parser.allow_partial_values = True
# then go ahead and parse
parser.parse()
于 2012-12-06T19:07:42.127 に答える
-1

回避策として、GitHub アーカイブ ファイルを行に分割し、各行を json として解析できます。

import json
with open('2013-05-31-10.json') as f:
    lines = f.read().splitlines()
    for line in lines:
        rec = json.loads(line)
        ...
于 2013-05-31T22:54:37.093 に答える