3

With Python 3, I want to read a JSON from url. This is what I got:

import json
import urllib.request
url_address = 'https://api.twitter.com/1.1/statuses/user_timeline.json'
with urllib.request.urlopen(url_address) as url:
    data = json.loads(url.read())
print(data)

However, it gives: HTTPError: HTTP Error 400: Bad Request

4
  • to me even browser gave {"errors":[{"code":215,"message":"Bad Authentication data."}]} Commented Dec 1, 2015 at 6:51
  • The url is of course an example, it should show: {"errors":[{"message":"The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview.","code":64}]} Commented Dec 1, 2015 at 6:53
  • To read json from url use requests that is best suited also convert the url address to ip address and add arguments to it. For further description read docs at (docs.python-requests.org/en/latest ) Commented Dec 1, 2015 at 6:54
  • Could this be my proxy server? Commented Dec 1, 2015 at 7:21

3 Answers 3

2

twitter is returning 400 code(bad request) so exception is firing. you can use try...except in your code sample and read exception body to get response json {"errors":[{"code":215,"message":"Bad Authentication data."}]}

import json
import urllib.request
from urllib.error import HTTPError


try:

    url_address ='https://api.twitter.com/1.1/statuses/user_timeline.json'
    with urllib.request.urlopen(url_address) as url:
        data = json.loads(url.read())
        print(data)

except HTTPError as ex:
    print(ex.read())
Sign up to request clarification or add additional context in comments.

Comments

2

To me below code is working- in Python 2.7

import json
from urllib import urlopen
url_address = ['https://api.twitter.com/1.1/statuses/user_timeline.json']
for i in url_address:
    resp = urlopen(i)
    data = json.loads(resp.read())
print(data)

Output-

{u'errors': [{u'message': u'Bad Authentication data.', u'code': 215}]}

If you use requests module-

import requests
url_address = ['https://api.twitter.com/1.1/statuses/user_timeline.json']
for i in url_address:
    resp = requests.get(i).json()
    print resp

Output-

{u'errors': [{u'message': u'Bad Authentication data.', u'code': 215}]}

5 Comments

With Python 3 use urllib.request.urlopen. Still this doesnt work for me. Also another example url https://api.github.com/users/mralexgray/repos, I get the error: the JSON object must be str, not 'bytes'
data = json.loads(resp.read().decode()) did the job! Can you explain briefly the reason?
It is just explicitly saying to decode- but it supposed to occur.
Why are you iterating over a list with one element?
I just gave a sense in case of multiple element.
0

I prefer aiohttp, it's asynchronous. Last time I checked, urllib was blocking. This means that it will prevent other parts of the script from running while it itself is running. Here's an example for aiohttp:

import aiohttp
async with aiohttp.ClientSession() as session:
async with session.get('https://api.github.com/users/mralexgray/repos') as resp:

    print(await resp.json())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.