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
Antigen
V2EX  ›  Python

如何提取这组不标准的 JSON 数据( RSA 公钥)?愁了三天两夜了

  •  1
     
  •   Antigen · 2016-08-28 22:15:07 +08:00 · 2428 次点击
    这是一个创建于 3010 天前的主题,其中的信息可能已经有所发展或是发生改变。

    请求 URL 返回这些数据, Firebug 能解析出 JSON 。但是我用 Python 的 JSON 却行不通。我想提取 pubkey 。

    import requests
    
    html = requests.get('https://passport.baidu.com/v2/getpublickey?token=60421c54ebc1272b71e17aa61df10f6a&tpl=tb&apiver=v3&tt=1472291018527&gid=D644D04-1F08-4018-B0E7-6BE79F5C62A6&callback=bd__pcbs__8og8ph', cookies=cookie)
    

    返回:

    bd__pcbs__8og8ph({"errno":'0',"msg":'',"pubkey":'-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCssku00Ol\/q0t8V8sG\/5oAU76B\n2MXvGWOtmSHDFMK9PwWRLWgTbzynbTbLBvlueRuZX0hhNfGhi1JLrX9lW0HlxWkV\nnSkRAjHAHc7S9JzIEk86+ejWTS0cHHMqhk5\/16d2fuVYXNTDwGD8Hsf62JX2HXhe\nbgoJVhE3ZsVeoyxrowIDAQAB\n-----END PUBLIC KEY-----\n',"key":'QLEP4TeXLB236TtwcSSvHYk0aC24hAWF'})
    

    于是我用正则表达式:

    pubkey = re.findall(r'-----BEGIN PUBLIC KEY-----.+-----END PUBLIC KEY-----', html.text)[0]
    

    拿到了:

    -----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCssku00Ol\/q0t8V8sG\/5oAU76B\n2MXvGWOtmSHDFMK9PwWRLWgTbzynbTbLBvlueRuZX0hhNfGhi1JLrX9lW0HlxWkV\nnSkRAjHAHc7S9JzIEk86+ejWTS0cHHMqhk5\/16d2fuVYXNTDwGD8Hsf62JX2HXhe\nbgoJVhE3ZsVeoyxrowIDAQAB\n-----END PUBLIC KEY-----
    

    然后用来 RSA 加密,可是 RSA 要求是 b'',我就把 pubkey 转化成 bytes 。

    pubkey_bytes = bytes(pubkey, encoding='utf-8')
    

    可是里面的\n/转化成了\\n\\/,这样不行啊!

    b'-----BEGIN PUBLIC KEY-----\\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDxhuZTzdfRidIwKBYj8ziTd0rC\\ngNuZFxzdBStw8UYOtD+BKNJ4ccKgrkfAkRW4LlAB8MuNecoW8X0Cb\\/kvauobSa5r\\nM7DwIOQWtN9fCFCIe1Xa9gSdXYrL\\/0X57Dtmw\\/DXmzfMFGsbHnB9zCmgVAM9IGXo\\nZr9skrfXx\\/sRMtBZ5QIDAQAB\\n-----END PUBLIC KEY-----'
    

    RSA 公钥必须是这样的格式:

    #字符串:
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCssku00Ol/q0t8V8sG/5oAU76B
    2MXvGWOtmSHDFMK9PwWRLWgTbzynbTbLBvlueRuZX0hhNfGhi1JLrX9lW0HlxWkV
    nSkRAjHAHc7S9JzIEk86+ejWTS0cHHMqhk5/16d2fuVYXNTDwGD8Hsf62JX2HXhe
    bgoJVhE3ZsVeoyxrowIDAQAB
    -----END PUBLIC KEY-----
    
    #二进制:
    b'-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDX1kWowXZuatDRaPkjTNFA2hJ7\n857jM8oWgBJmS9JXZdJxFK70Th2cWsL8/cvLDzxs0lBaPtZwK7XvphipFXvCLDCn\naz58KJyrqiDrmNpDMPjIFzf6n+Bk0SQlW4KuNJoy3VS18AlS7v5gV7OvscQHPgNU\nGtUxUPdgKT5zsCT0+QIDAQAB\n-----END PUBLIC KEY-----'
    

    三天两夜了,实在是找不到解决办法了。最后搜肠刮肚用了这么个办法:

    re.sub(r'\\/', r'/', re.sub(r'\\n', r'\n', pubkey))    #把 pubkey 里面的\\n 和\/替换成\n 和 /
    

    有没有更好的办法?

    第 1 条附言  ·  2016-08-30 22:38:34 +08:00

    该问题已经解决!附上解决办法:

    无论请求的URL是什么,返回的代码都不是标准的JSON代码。并不是因为被bd__pcbs__8og8ph包括起来了,也不是3楼说的,去掉bd__pcbs__8og8ph参数就可以被JSON解析。是因为返回的代码里有单引号的键值对。

    通过html.text拿到字符串,使用正则re.sub把其中的单引号替换成双引号,然后使用json.loads声明成JSON对象,最后pubkey_json[pubkey]拿到其中的pubkey。

    具体代码如下:

    pubkeyHtml = requests.get('https://passport.baidu.com/v2/getpublickey?token=60421c54ebc1272b71e17aa61df10f6a&tpl=tb&apiver=v3&tt=1472291018527&gid=D644D04-1F08-4018-B0E7-6BE79F5C62A6&ie=utf-8', cookies=cookie)    #无论是否带入`bd__pcbs__8og8ph`参数都可以
    pubkeyStr = re.sub(r'\'', r'"', pubkeyHtml.text)    #替换单引号
    pubkey = json.loads(pubkeyStr)['pubkey']    #创建JSON对象并拿到pubkey字符串
    print('当前提取到的pubkey是:', pubkey)
    
    maowu
        1
    maowu  
       2016-08-29 01:00:31 +08:00 via Android
    好奇 py 的 json 报了什么错误
    0x5e
        2
    0x5e  
       2016-08-29 09:05:54 +08:00
    bd__pcbs__8og8ph()括号里的提取出来,然后 json.loads()?
    Antigen
        4
    Antigen  
    OP
       2016-08-29 11:57:32 +08:00
    @0x5e 太感谢了,十分感谢,万分感谢,谢谢你,鸡动的无法言表。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4048 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 05:15 · PVG 13:15 · LAX 21:15 · JFK 00:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.