2013-03-04 13 views
6

KISSmetricsは、解析する必要がある無効なJSON文字列を生成します。無効なJSONエスケープの固定

for line in lines: 
    try: 
     data = self.clean_data(json.loads(line)) 
     except ValueError, e: 
      logger.error('%s: %s' % (e.message, line)) 

例生データ:

{"search engine":"Google","_n":"search engine hit","_p":"kvceh84hzbhywcnlivv+hdztizw=","search terms":"military sound effects programs","_t":1356034177} 

は、クリーンアップのチャンスは、この厄介なJSONがあり、それを解析し、私は

ERROR 2013-03-04 04:31:12,253 Invalid \escape: line 1 column 132 (char 132): {"search engine":"Google","_n":"search engine hit","_p":"z392cpdpnm6silblq5mac8kiugq=","search terms":"happy new year animation 1920\303\2271080 hd","_t":1356390128} 

ERROR 2013-03-04 04:34:19,153 Invalid \escape: line 1 column 101 (char 101): {"search engine":"Google","_n":"ad campaign hit","_p":"byskpczsw6sorbmzqi0tk1uimgw=","search terms":"\331\203\330\261\330\252\331\207 \331\201\331\212\330\257\331\212\330\244\331\211 \330\256\331\212\331\204\330\247\330\255\331\211 \331\203\331\210\330\261\330\257\331\211","_t":1356483052} 

私のコードのようなエラーのトンを取得していますか?ご協力いただきありがとうございます。

+0

?デコードする前の値の 'repr()'とは何ですか? –

+0

ああ、入力データには* 8進数のエスケープがあります。本当に無効なJSONです。 –

答えて

11

入力データには8進エスケープが含まれています。彼らは実際に無効になります。これは、あなたの入力作業を行い

import re 

invalid_escape = re.compile(r'\\[0-7]{1,3}') # up to 3 digits for byte values up to FF 

def replace_with_byte(match): 
    return chr(int(match.group(0)[1:], 8)) 

def repair(brokenjson): 
    return invalid_escape.sub(replace_with_byte, brokenjson) 

:正規表現を使用して復号化されたバイトに置き換える

>>> data1 = r"""{"search engine":"Google","_n":"search engine hit","_p":"z392cpdpnm6silblq5mac8kiugq=","search terms":"happy new year animation 1920\303\2271080 hd","_t":1356390128}""" 
>>> json.loads(repair(data1)) 
{u'_n': u'search engine hit', u'search terms': u'happy new year animation 1920\xd71080 hd', u'_p': u'z392cpdpnm6silblq5mac8kiugq=', u'_t': 1356390128, u'search engine': u'Google'} 
>>> print json.loads(repair(data1))['search terms'] 
happy new year animation 1920×1080 hd 
>>> data2 = r"""{"search engine":"Google","_n":"ad campaign hit","_p":"byskpczsw6sorbmzqi0tk1uimgw=","search terms":"\331\203\330\261\330\252\331\207 \331\201\331\212\330\257\331\212\330\244\331\211 \330\256\331\212\331\204\330\247\330\255\331\211 \331\203\331\210\330\261\330\257\331\211","_t":1356483052}""" 
>>> json.loads(repair(data2)){u'_n': u'ad campaign hit', u'search terms': u'\u0643\u0631\u062a\u0647 \u0641\u064a\u062f\u064a\u0624\u0649 \u062e\u064a\u0644\u0627\u062d\u0649 \u0643\u0648\u0631\u062f\u0649', u'_p': u'byskpczsw6sorbmzqi0tk1uimgw=', u'_t': 1356483052, u'search engine': u'Google'} 
>>> print json.loads(repair(data2))['search terms'] 
كرته فيديؤى خيلاحى كوردى 
+0

あなたは素晴らしいです。どうもありがとう! –

+0

調整済み。バイトは最大3オクテットしかなく、UTF-8を8進数にエンコードするので、代わりに 'chr()'を使う必要があります。 –

1

この正確なシナリオのためcjsonを考えてみましょう(https://pypi.python.org/pypi/python-cjson

は(エスケープオクタルを扱うように思えます迅速)。

+0

これは私の問題を完全に解決しました。ありがとう。 –

+0

OSXでコンパイルに失敗する(pip3インストール) – user2707001

0

私は同様の問題を抱えていましたが、jsonライブラリをjamlに置き換えて問題を解決しました。 (YAMLはJSONと互換性があります。)

例:あなたはJSONをパースするにはどうすればよい

import yaml 

obj = yaml.load(json_string) # instead of json.loads(json_string) 
関連する問題