V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
northisland
V2EX  ›  Python

python2.7 的 json 模块,真是蛋疼啊,读东西老报错。

  •  
  •   northisland · 2016-08-19 09:19:41 +08:00 · 11804 次点击
    这是一个创建于 2806 天前的主题,其中的信息可能已经有所发展或是发生改变。
    读个啥东西,都挑毛病,

    前段时间 javascript 生成的 json ,现在用 python 里的 json.load 读,
    就这个文件:
    http://123.206.64.183/bookmark_data.json

    python 读,总说:
    Traceback (most recent call last):
    File "ExtensionJsonMiner.py", line 20, in <module>
    print getJsonData('bookmark_data.json')
    File "ExtensionJsonMiner.py", line 16, in getJsonData
    return json.load(f)
    File "/usr/lib/python2.7/json/__init__.py", line 290, in load
    **kw)
    File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
    File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
    raise ValueError("No JSON object could be decoded")
    ValueError: No JSON object could be decoded


    这跟字符编码没关系了,因为我把 utf-8 全用 encodeURI 转成 ASCII 了。

    可是还是报错。

    觉得问题是这个库,太挑 json 语法毛病。

    请问各位什么意见?
    第 1 条附言  ·  2016-08-19 10:16:58 +08:00
    在各位的帮助下,问题顺利解决了。

    正如 @SErHo 所说:
    我这里遇到的问题是,把系统标记给文件 bom 码,一起输送给了 json 模块~

    BOM ( Byte Order Mark ),字节顺序标记,出现在文本文件头部, Unicode 编码标准中用于标识文件是采用哪种格式的编码。

    用最普通的文件对象, read 方法,会读入 BOM 。
    所以用 @realityone 提供的

    json.load(codecs.open('bookmark_data.json', 'r', 'utf-8-sig'))

    能避免读入 BOM ,是个好办法。

    @Kisesy 直接用 http get 方法,也避免了读入 BOM 。


    另外,如 @mgna17 所说, yaml 是处理不规范的 json 的好工具,带 BOM 的 json 也可以处理。
    但是时间耗费上,大概是 3.03: 0.02 ,会多花太多时间。


    感谢各位支招~帮我提高了
    15 条回复    2016-08-19 12:20:26 +08:00
    knightdf
        1
    knightdf  
       2016-08-19 09:29:34 +08:00   ❤️ 1
    用 load 和 loads 都测试过了,完全没问题
    northisland
        2
    northisland  
    OP
       2016-08-19 09:36:34 +08:00
    @knightdf
    我这里还是悲剧的,请问你用的是哪个版本的 python ?

    Python 2.7.6 (default, Mar 22 2014, 22:59:56)
    [GCC 4.8.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.

    >>> f = open('/var/www/html/bookmark_data.json', 'r')
    >>> s = f.read()
    >>> f.close()

    >>> import json
    >>> json.loads(s)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python2.7/json/__init__.py", line 338, in loads
    return _default_decoder.decode(s)
    File "/usr/lib/python2.7/json/decoder.py", line 366, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File "/usr/lib/python2.7/json/decoder.py", line 384, in raw_decode
    raise ValueError("No JSON object could be decoded")
    ValueError: No JSON object could be decoded

    >>> print s[:100]
    {"data":[{"id":"0","dateAdded":1471567289926},{"id":"1","title":"Bookmarks%20bar","parentId":"0",
    mgna17
        3
    mgna17  
       2016-08-19 09:40:35 +08:00   ❤️ 1
    试试 yaml.load
    可以直接读不规范的 json
    billion
        4
    billion  
       2016-08-19 09:42:58 +08:00
    这种情况一般来说是你的 Json 格式不规范。例如列表的末尾元素后面多了一个逗号。

    你先用在线的 json 格式检查网站检查一下你的这个 json 的字符串是否规范。
    SErHo
        5
    SErHo  
       2016-08-19 09:43:39 +08:00   ❤️ 2
    >>> file("bookmark_data.json")
    <open file 'bookmark_data.json', mode 'r' at 0x106d8ec00>
    >>> x = _.read()
    >>> x[:10]
    '\xef\xbb\xbf{"data"'
    >>>

    看样子文件开头有 BOM 头,去掉就可以正常 load 了。
    realityone
        6
    realityone  
       2016-08-19 09:43:42 +08:00   ❤️ 1
    json.load(codecs.open('bookmark_data.json', 'r', 'utf-8-sig'))
    SErHo
        7
    SErHo  
       2016-08-19 09:45:08 +08:00   ❤️ 1
    补充一下,这个并不是 Python 的问题,你这个用 ruby, nodejs 之类的也解析不出来, UTF8 文件不需要 BOM 头。
    northisland
        8
    northisland  
    OP
       2016-08-19 09:45:41 +08:00
    @mgna17 多谢, yaml 好用, load 时间略长与 json 。
    Kisesy
        9
    Kisesy  
       2016-08-19 09:48:16 +08:00   ❤️ 1
    是不是 json 模块的问题,你这样试试
    import requests
    r = requests.get('http://123.206.64.183/bookmark_data.json')
    print(r.json())
    knightdf
        10
    knightdf  
       2016-08-19 09:49:15 +08:00   ❤️ 1
    @northisland 我是把你提供的 json 下下来读的, 2.7.12
    bearqq
        11
    bearqq  
       2016-08-19 09:51:26 +08:00 via Android   ❤️ 1
    SErHo 是正解,其实不该 json 背锅,你在读取时犯的错
    northisland
        12
    northisland  
    OP
       2016-08-19 09:54:14 +08:00
    @bearqq 同意。这不是 python 中 json 头的问题。

    我该去补补 bom 头的知识了~
    21grams
        13
    21grams  
       2016-08-19 11:22:43 +08:00 via Android
    python 哭晕了
    quxw
        14
    quxw  
       2016-08-19 12:12:41 +08:00
    推荐去听 《内核恐慌》 和 《字谈自唱》 的《字谈字串》
    9hills
        15
    9hills  
       2016-08-19 12:20:26 +08:00 via iPhone
    BOM 是个很烂的东西。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4658 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 10:03 · PVG 18:03 · LAX 03:03 · JFK 06:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.