JSONシリアル化のバリエーションに対処する適切な方法
-
05-07-2019 - |
質問
PythonのSimpleJSONを使用してJSONをシリアル化するWebサービスと、Googleの視覚化 API 。 Google Data TableのQueryメソッドを使用してJSONレスポンスを読み取ろうとすると、「無効なラベル」が表示されます。エラー。
Googleスプレッドシートは、オブジェクトキーを引用符で囲まずにJSONを出力することに気付きました。引用符なしでJSONを読んでみたところ、うまくいきました。 SimpleJSON出力を取得して
を使用してGoogle datableに読み込む最良の方法は何だろうと思っていました。 query = new google.visualization.Query(" http://www.myuri.com/api/")
。
引用符を削除するために正規表現を使用できますが、それはずさんなようです。私が試したjavascript JSON解析ライブラリは、オブジェクトキーを引用符で囲まずにJSON構文で読み取ることはできません。
オブジェクトキーの前後のre:引用を読むための良い背景があります:
解決
Google APIがJSONを期待しているのは確かですか?私の経験では、GoogleのAPIは、あなたが説明している方法で大規模に破損する傾向はありません。実際には、JSONに似た別のフォーマットを期待している可能性があります。
さらに突っ込むと、Googleが期待する形式でデータを取得するための手順が明らかになります:
たとえば、dataSourceUrlを取得するには Googleスプレッドシートから、 次:
- スプレッドシートで、セルの範囲を選択します。
- メニューから「挿入」を選択してから、「ガジェット」を選択します。
- 右上のセレクタをクリックしてガジェットのメニューを開きます。
- 「Get source source URL」メニューオプションを選択します。
これを実行して、ブラウザでURLを開きました。返されたデータは確かにJSONではありませんでした:
google.visualization.Query.setResponse(
{requestId:'0',status:'ok',signature:'1464883469881501252',
table:{cols: [{id:'A',label:'',type:'t',pattern:''},
{id:'B',label:'',type:'t',pattern:''}],
rows: [[{v:'a'},{v:'h'}],[{v:'b'},{v:'i'}],[{v:'c'},{v:'j'}],[{v:'d'},{v:'k'}],[{v:'e'},{v:'l'}],[{v:'f'},{v:'m'}],[{v:'g'},{v:'n'}]]}});
結果はブラウザによって直接実行されることを意図しているようです。コードを次のように変更してみてください。
# old
return simplejson.dumps ({"requestId": 1, "status": "ok", ...})
# new
json = simplejson.dumps ({"requestId": 1, "status": "ok", ...})
return "google.visualization.Query.setResponse(%r);" % json
他のヒント
"無効なラベル"エラーは通常、JSON文字列のブラインドeval()によるもので、プロパティ名がラベルと間違えられます(同じ構文--quot; foo:"を持っているため)。
eval("{ foo: 42, bar: 43 }"); // Results in invalid label
簡単な解決策は、JSON文字列に中括弧を囲む括弧があることを確認することです:
eval("({ foo: 42, bar: 43 })"); // Works
JSON文字列を括弧で囲んで、「無効なラベル」がエラーはなくなります。
判明したように、:mod:json は、一重引用符で囲まれた文字列を抑制します。これは物事を整理します:
JavaScriptオブジェクトをPythonでJSONとして解析する:
解決策:
>>> from re import sub
>>> import json
>>> js = "{ a: 'a' }"
>>> json.loads(sub("'", '"', sub('\s(\w+):', r' "\1":', js)))
{u'a': u'a'}
編集:(エッジケースのレビュー)
したがって、提案された解決策はすべての場合、具体的には次のようなものに対処できないことが判明しました
e.g。 {foo:" a statement:right here!"}は{" foo&quot ;:" a" sentence&quot ;: right here!"}
に変更されます –ジェイソンS 4月12日18:03
これを解決するには、単に文字列のコロンではなく、実際にキーで作業していることを確認する必要があるため、マジックの後ろを少し見て、コンマ(、)または中括弧({ )存在を確認して、適切に使用できるようにします:
文字列のコロン:
>>> js = "{foo: 'a sentence: right here!'}"
>>> json.loads(sub("'", '"', sub('(?<={|,)\s*(\w+):', r' "\1":', js)))
{u'foo': u'a sentence: right here!'}
もちろん、これは以下と同じです:
>>> js = "{foo: 'a sentence: right here!'}"
>>> json.loads(sub('(?<={|,)\s*(\w+):', r' "\1":', js).replace("'",'"'))
{u'foo': u'a sentence: right here!'}
しかし、私はこれが唯一の欠陥ではないことを指摘しました。なぜなら、引用についてはどうですか:
引用符のエスケープについても懸念がある場合は、文字列を構成する要素についてもう少し具体的にする必要があります。最初の引用符は中括弧({)、スペース(\ s)またはコロン(:)の後に続き、最後に一致する引用符はコンマ(、)または閉じ中括弧(})の前に来るため、以下のように、同じ文字列の一部としての間にあるすべてのもの:
文字列内の追加の引用符:
>>> js = "{foo: 'a sentence: it\'s right here!'}"
>>> json.loads(
... sub("(?<=\s|{|:)'(.*?)'(?=,|})",
... r'"\1"',
... sub('(?<={|,)\s*(\w+):', r' "\1":', js))
... )
{u'foo': u"a sentence: it's right here!"}
より多くのエッジケースが明らかになり解決されるので、このスペースを見てください。別のものを見つけることができますか?
またはより複雑なものの場合、 npm view
によって返される実際の例:
From:
{ name: 'chuck', description: 'Chuck Norris joke dispenser.', 'dist-tags': { latest: '0.0.3' }, versions: '0.0.3', maintainers: 'qard ', time: { '0.0.3': '2011-08-19T22:00:54.744Z' }, author: 'Stephen Belanger ', repository: { type: 'git', url: 'git://github.com/qard/chuck.git' }, version: '0.0.3', dependencies: { 'coffee-script': '>= 1.1.1' }, keywords: [ 'chuck', 'norris', 'jokes', 'funny', 'fun' ], bin: { chuck: './bin/chuck' }, main: 'index', engines: { node: '>= 0.4.1 < 0.5.0' }, devDependencies: {}, dist: { shasum: '3af700056794400218f99b7da1170a4343f355ec', tarball: 'http://registry.npmjs.org/chuck/-/chuck-0.0.3.tgz' }, scripts: {}, directories: {}, optionalDependencies: {} }
宛先:
{u'author': u'Stephen Belanger ', u'bin': {u'chuck': u'./bin/chuck'}, u'dependencies': {u'coffee-script': u'>= 1.1.1'}, u'description': u'Chuck Norris joke dispenser.', u'devDependencies': {}, u'directories': {}, u'dist': {u'shasum': u'3af700056794400218f99b7da1170a4343f355ec', u'tarball': u'http://registry.npmjs.org/chuck/-/chuck-0.0.3.tgz'}, u'dist-tags': {u'latest': u'0.0.3'}, u'engines': {u'node': u'>= 0.4.1 < 0.5.0'}, u'keywords': [u'chuck', u'norris', u'jokes', u'funny', u'fun'], u'main': u'index', u'maintainers': u'qard ', u'name': u'chuck', u'optionalDependencies': {}, u'repository': {u'type': u'git', u'url': u'git://github.com/qard/chuck.git'}, u'scripts': {}, u'time': {u'0.0.3': u'2011-08-19T22:00:54.744Z'}, u'version': u'0.0.3', u'versions': u'0.0.3'}
Works for me =)
nJoy!