25
import json
import requests

url = 'http://developer.usa.gov/1usagov.json'
r = requests.get(url, stream=True)

for line in r.iter_lines():
    if line:
        print (json.loads(line))

Gives this error:

TypeError: can't use a string pattern on a bytes-like object

While viewing through the browser i do see that the response is a Json but request library says its a bytes like object why so ?

sjakobi
  • 3,546
  • 1
  • 25
  • 43
user3249433
  • 591
  • 3
  • 9
  • 18

1 Answers1

37

If you use Python 3.x, you should pass str object to json.loads.

Replace following line:

print(json.loads(line))

with:

print(json.loads(line.decode()))

UPDATE: The behavior changed in Python 3.6. The argument can now be of type bytes or bytearray. The input encoding should be UTF-8, UTF-16 or UTF-32.

falsetru
  • 357,413
  • 63
  • 732
  • 636
  • @nehemiah I'd rather get an exception than have a bug in my code. – Aran-Fey May 21 '18 at 22:58
  • No, json loads expects a string, which means it would coerce(try to convert) the incoming object into string, which is what happens in p2 and it's very pythonic. Why do you think this will lead to a bug? – nehem May 21 '18 at 23:47
  • @nehemiah, Behavior changed in Python 3.6: Changed in version 3.6: s can now be of type bytes or bytearray. The input encoding should be UTF-8, UTF-16 or UTF-32. (https://docs.python.org/3/library/json.html#json.loads) This question is tagged python-3.x, so I answered based on Python 3.x behavior (prior to Python 3.6). – falsetru May 22 '18 at 00:59