Q:

Python 3 Urlopen problems

I know it's been heavily documented and I've tried to place the .read().decode('utf-8') everywhere I think it should go but I'm still missing something and I'm not sure where else to turn. I've got a script that works fine in Python 2.7 to scrape ESRI REST URL's for data by fetching the object ID's. However, it does not seem to be cooperating in Python 3. It continuously fails on line 29 (see below). Any help would be GREATLY appreciated. 
        version = json.loads(webresp.decode('utf-8'))['currentVersion']

I'm always getting this error consistently:
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    main(url, jsonfilelocation, jsonfilename)
  File "\\SERVER\Projects\Python\TOUCH\esrirestjson.py", line 73, in main
    oids = ESRIJSON().getobjrange(webconn, path)
  File "\\SERVER\Projects\Python\TOUCH\esrirestjson.py", line 29, in getobjrange
    version = json.loads(webresp.decode('utf-8'))['currentVersion']
  File "C:\ArcGISPro\bin\Python\envs\arcgispro-py3\lib\json\__init__.py", line 312, in loads
    s.__class__.__name__))
TypeError: the JSON object must be str, not 'bytes'

A:

I got your error fixed by changing json.loads() to json.load and removed all the decode('utf-8'). Now I encounter another bug due to you not handling string formatting properly in Python 3. The qs variables need to be in the format "?where=&outFields=*&returnGeometry={}.format(variable to add to string) which saves tons of worrying about encoding issues. I am still getting ascii errors with that qs string but hopefully this points you in the right direction. Python 3 is 10x better than 2.7 and well worth the effort.

