无法从Google解码Json

时间:2013-08-08 12:12:27

标签: php json

好吧,我正在尝试从Google Suggest工具中检索一些信息。

问题是,json在请求后返回,似乎无法解码(使用json_decode)+ JSONLint将其视为“无效”。

怎么了?

{
    e: "GooDUs7lFIeXO63LgBA",
    c: 0,
    u: "https://www.google.com/s?gs_rn\x3d24\x26gs_ri\x3dpsy-ab\x26tok\x3dt8ORbtI13MEFLoCQjPSv6w\x26cp\x3d2\x26gs_id\x3d3i\x26xhr\x3dt\x26q\x3dtemplate\x26es_nrs\x3dtrue\x26pf\x3dp\x26safe\x3doff\x26sclient\x3dpsy-ab\x26oq\x3d\x26gs_l\x3d\x26pbx\x3d1\x26bav\x3don.2,or.r_cp.r_qf.\x26bvm\x3dbv.50500085,d.bGE\x26fp\x3dc513cf9c63a02102\x26biw\x3d1304\x26bih\x3d437\x26tch\x3d1\x26ech\x3d20\x26psi\x3dFYkDUs-xCsrT4QTD9YGwDw.1375963413783.1",
    p: true,
    d: "[\x22template\x22,[[\x22template\\u003cb\\u003es\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003e monster\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003e c++\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003es for pages\\u003c\\/b\\u003e\x22,0]],{\x22t\x22:{\x22bpc\x22:false,\x22tlw\x22:false},\x22q\x22:\x22YjrI_EdhVrEkZrkqZwaGIJ_Ih4c\x22,\x22j\x22:\x223i\x22}]"
}

这就是JSONLint给出的错误:

Parse error on line 1:
{    e: "GooDUs7lFIeXO63L
-----^
Expecting 'STRING', '}'

PS 即使在编辑"e":之后仍然如此,它仍会发出有关u的值的错误,并声称它期待{{1} }或STRING等......:S

3 个答案:

答案 0 :(得分:1)

问题中给出的代码是有效的JSON。

为了成为有效的JSON,需要使用引号命名的字段。 e变量名称或其他任何名称都没有引号。

这就是JSON解码器所抱怨的:它希望看到"e",而不是e

此外,JSON不接受\x转义格式(十六进制中的字符引用);它只能使用\u格式(十进制的unicode字符引用)。您提供的代码包括两种格式的转义字符。

问题是,您使用的是官方Google API吗?因为他们通常擅长提供有效的JSON。这不是有效的JSON,因此您可能没有使用正确的API。另一个线索是变量名称不是很有意义;官方API通常会提供更有意义的变量名称。如果它是正确的API,您应该尝试通过谷歌提出一张票来修复它;破解JSON并不好,但要修复它们应该是微不足道的。

假设你无法让他们修复它,我们找不到可以提供有效数据的替代API位置,我们如何处理我们得到的内容?

虽然此代码可能不是有效的JSON,但它作为Javascript对象有效(JSON规则比普通Javascript规则更严格)。因此,如果您足够信任它,可以使用eval()在Javascript解释器中运行它。

唯一的另一个替代方法是在解析字符串之前修复字符串,以便引用变量名称。这有点痛苦,但如果输出是一致的话,它是可行的。如果它发生了变化,你会遇到问题(如果它是一个非官方的API,那么它可能会在没有警告的情况下随时发生)。

答案 1 :(得分:0)

问题在于字符串中的backslashes(用于转义字符)

在PHP 5.4中,您可以使用JSON_UNESCAPED_SLASHES

echo json_encode(JSON_STRING, JSON_UNESCAPED_SLASHES);

否则,您可以进行更换 -

str_replace('\\/', '/', json_encode(JSON_STRING));

由于\/是表示/

的有效方式

答案 2 :(得分:0)

好的,所以这就是我最终做的事情(完全不优雅,但它有效):

    $content = preg_replace_callback(
      "(\\\\x([0-9a-f]{2}))i",
      function($a) {return chr(hexdec($a[1]));},
      $content
    );
    $content = str_replace("e:","\"e\":",$content);
    $content = str_replace("c:","\"c\":",$content);
    $content = str_replace("u:","\"u\":",$content);
    $content = str_replace("p:","\"p\":",$content);
    $content = str_replace("d:","\"d\":",$content);
    $content = str_replace("\"[","[",$content);
    $content = str_replace("]\"","]",$content);

    $content = json_decode($content);