0

I am having difficulty parsing a json string that appears to be valid json.

My code is the following. I'm trying to grab some simple json from a URL.

import urllib2    
import simplejson
req = urllib2.Request("http://www.rentrent.org/RENT/Ads.aspx?xmin=-118.01925659179687&ymin=33.71948521132481&xmax=-117.68142700195314&ymax=33.85644642218431&bd=&ba=&pets=-1&type=2&throwErrorIfOverLimit=false&callback=xxx")  

opener = urllib2.build_opener()    
f = opener.open(req)    
content = f.read();    
print "content = " + content   # Appears to print valid json string
json = simplejson.loads(content)

I get an error on simplejson.loads(content):

raise JSONDecodeError("No JSON object could be decoded", s, idx) 
simplejson.decoder.JSONDecodeError: No JSON object could be decoded: line 1 column 0 (char 0)

This is confusing because content appears to be a perfectly good json string.

I need to get to this data as individual elements. Any ideas how to get rid of this error?

codingJoe
  • 4,713
  • 9
  • 47
  • 61
  • 3
    Can you post the JSON response? – Blender Apr 29 '12 at 02:15
  • 1
    You can get rid of the error by giving it valid json, or ignoring the failure. Need to see json. – jdi Apr 29 '12 at 02:19
  • I wanted to correct my last comment by saying we don't need to see the json at this point. I looked at the url and saw the data, though its convenient for everyone if a snippet is posted here. – jdi Apr 29 '12 at 04:30

1 Answers1

3

This is a jsonp api url. Its expecting to return to you a response wrapped in a function call xxx(). Look into how to handle jsonp. What you are currently getting is not actually valid jsonp. Its valid javascript.

Here is another question about the difference:
What are the differences between JSON and JSONP?

You can remove the callback param from your url and get back pure json:
http://www.rentrent.org/RENT/Ads.aspx?xmin=-118.01925659179687&ymin=33.71948521132481&xmax=-117.68142700195314&ymax=33.85644642218431&bd=&ba=&pets=-1&type=2&throwErrorIfOverLimit=false

Update

I overlooked that removing the callback param from the url doesn't actually tell this api to return JSON. It only prevents it from being wrapped into a function. The return value is still not json. It is javascript. To be specific, here is an example:

Javascript From the return value

{Status:'Success',

JSON

{'Status':'Success',

All of the keys need to be quoted. Your options are either:

  1. See if the api supports a json return value instead of jsonp
  2. Do a regex fix on the output to quote all of the keys before decoding
Community
  • 1
  • 1
jdi
  • 90,542
  • 19
  • 167
  • 203
  • Thanks! I see how it is no longer wrapped in a function call. However it still won't parse. I get a `raise JSONDecodeError("Expecting property name", s, end) simplejson.decoder.JSONDecodeError: Expecting property name: line 1 column 1 (char 1)` Does that url return a valid json or am I parsing it incorrectly? – codingJoe Apr 29 '12 at 04:28
  • Some APIs (like Stripe's for example) will return JSONP if callback argument is provided, JSON otherwise. – btk Mar 10 '13 at 04:03