0

phpmyadminからエクスポートされたjsonファイルがあります。次のようになります(utf-8ファイル):

[{"user_email": "bh549@sina.cn","followee_id": 1411833182,"create_date": "cdatetime datetime p1 (S\'\\x07\\xdb\\x06\\x13\\x16\\x08(\\r\\xd5\\xcc\' tRp2 ."}, {"user_email": "zaici4@sina.cn","followee_id": 1296426000,"create_date": "cdatetime datetime p1 (S\'\\x07\\xdb\\x07\\x14\\x179\\x16\\x02 \\x08\' tRp2 ."}, {"user_email": "yanaa357@sina.com","followee_id": 1848085255,"create_date": "cdatetime datetime p1 (S\'\\x07\\xdb\\x08\\x13\\x17\\x10\\x0f\\x05\\x1c\\x02\' tRp2 ."}]

各dictはデータベース内の行であり、各行の3番目の値はcpickled文字列です。

次に、フォームを使用して、このファイルをPythonスクリプトにアップロードします(postメソッドを使用)。

次に、このファイルを次のようにPythonスクリプトで解析します。

   import cgi, os
    import cgitb; cgitb.enable()
    import json
    #import simplejson as json
    print "Content-type: text/html\n\n"
    try:
        import msvcrt
        msvcrt.setmode (0, os.O_BINARY) # stdin = 0
        msvcrt.setmode (1, os.O_BINARY) # stdout = 1
    except ImportError:
        pass

    form = cgi.FieldStorage()

    file_content = form['mysql_table'].value
    file_content = json.loads(file_content)

次に、ブラウザはjson.loadsを実行するときに値エラーを出力します。

<type 'exceptions.ValueError'>: Invalid control character at: line 1 column 83 (char 83)

char 83は、最初の行の3番目の値のスペースです。

この問題を解決するにはどうすればよいですか?

とにかくmhawkeに感謝します。しかし、あなたが言った最初の問題は存在しません。印刷結果からコピーしたので、\ nはありません。エクスポートしたjsonファイルには、実際には\ n

{"user_email": "bh549@sina.cn","followee_id": 1411833182,"create_date": "cdatetime
datetime
p1
(S\'\\x07\\xdb\\x06\\x13\\x16\\x08(\\r\\xd5\\xcc\'
tRp2
."}, {"user_email": "zaici4@sina.cn","followee_id": 1296426000,"create_date": "cdatetime
datetime
p1
(S\'\\x07\\xdb\\x07\\x14\\x179\\x16\\x02 \\x08\'
tRp2
."}

私は誤解していますか?2番目の問題、エクスポート時にphpmyadminがファイルをエスケープすることです。次に、あなたが言った問題を修正する方法は?

slouton:テーブルをエクスポートしてピクルスにしたデータを変換するPythonスクリプトを書いています。これで機能し、ピクルス化されたデータでjsonを処理する方法のようです。

4

3 に答える 3

1

改行はJSONの文字列では無効です。phpMyAdminが改行を生成している場合は、プロジェクトのバグをログに記録する必要があります。

>>> json.loads('"123"')
u'123'
>>> json.loads('"123\n456"')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib64/python2.7/json/decoder.py", line 382, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Invalid control character at: line 1 column 4 (char 4)
于 2012-06-15T03:41:24.807 に答える
0

JSONは、のような16進エスケープをサポートしていません\x07。代わりにUnicodeエスケープを使用する必要があります(\u0007)。デコードする前に、ある形式を別の形式に変換してみてください。

content = content.replace('\\x', '\\u00')
于 2012-06-12T07:37:32.483 に答える
0

いくつかの問題があります。

一つ目は、漬物が無効に見えることです(私は思います)。さまざまなコンポーネント間に改行文字がありません。例えば

import cPickle
bad_pickle = "cdatetime datetime p1 (S\'\\x07\\xdb\\x06\\x13\\x16\\x08(\\r\\xd5\\xcc\' tRp2 ."
good_pickle = '\n'.join(bad_pickle.split())

>>> cPickle.loads(bad_pickle)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
cPickle.UnpicklingError: pickle data was truncated

>>> cPickle.loads(good_pickle)
datetime.datetime(2011, 6, 19, 22, 8, 40, 906700)

\2番目の問題は、さらに別のでエスケープをエスケープする必要があることです\replaceたとえば、を使用してこれを簡単に行うことができますreplace('\\', '\\\\')

このコードは、ピクルス化されたオブジェクトを含むラウンドトリップJSONエンコーディングとデコーディングを示しています。

import json, cPickle
from datetime import datetime

pickled_datetime = cPickle.dumps(datetime.now())
d = {"user_email": "bh549@sina.cn",
     "followee_id": 1411833182,
     "create_date": pickled_datetime }
j = json.dumps(d)

>>> d
{'create_date': "cdatetime\ndatetime\np1\n(S'\\x07\\xdc\\x06\\r\\x0c\\x16:\\x06/\\x85'\ntRp2\n.", 'followee_id': 1411833182, 'user_email': 'bh549@sina.cn'}
>>> j
'{"create_date": "cdatetime\\ndatetime\\np1\\n(S\'\\\\x07\\\\xdc\\\\x06\\\\r\\\\x0c\\\\x16:\\\\x06/\\\\x85\'\\ntRp2\\n.", "followee_id": 1411833182, "user_email": "bh549@sina.cn"}'

jのバックスラッシュが追加のバックスラッシュによってどのようにエスケープされているかに注意してください。これは、データベースからのピクルスがどのように見えるかです。に保存されているJSONデータのデコードは次のjように行われます。

d2 = json.loads(j)
cPickle.loads(d2['create_date'])

>>> d2
{'followee_id': 1411833182, 'create_date': "cdatetime\ndatetime\np1\n(S'\\x07\\xdc\\x06\\r\\x0c\\x16:\\x06/\\x85'\ntRp2\n.", 'user_email': 'bh549@sina.cn'}
>>> cPickle.loads(d2['create_date'])
datetime.datetime(2012, 6, 13, 12, 22, 58, 405381)
于 2012-06-13T03:31:18.790 に答える