Python urllib2: Отримати відповідь JSON від url


89

Я намагаюся ОТРИМАТИ URL-адресу за допомогою Python, і відповідь JSON. Однак коли я біжу

import urllib2
response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
html=response.read()
print html

Html має тип str, і я очікую JSON. Чи є спосіб, яким я можу захопити відповідь як JSON або словник python замість str.


1
Чи response.read()повертається дійсний рядок JSON?
Мартін Пітерс

Так, це дійсний рядок JSON його just або type str, а не dict
Deepak B

Якщо це JSON-представлення рядка, а не JSON-об'єкт (dict), ви не можете примусити сервер повертати вам різні дані; вам, мабуть, потрібно зробити інший запит. Якщо ви просто не знаєте, як проаналізувати представлення JSON на еквівалентний об’єкт Python, відповідь Мартіна Пітерса правильна.
abarnert

Відповіді:


182

Якщо URL-адреса повертає дійсні дані, закодовані JSON, використовуйте jsonбібліотеку для декодування:

import urllib2
import json

response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
data = json.load(response)   
print data

1
@ ManuelSchneid3r: Відповідь тут на Python 2, де читання з responseдає вам bytestring і json.load()очікує прочитати bytestring. JSON повинен кодуватися за допомогою кодека UTF, і вищезазначене працює для UTF-8, UTF-16 та UTF-32, за умови, що для останніх двох кодеків включена кодова специфікація. Відповідь, на яку ви посилаєтесь, передбачає використання UTF-8, що, як правило, є правильним, оскільки це за замовчуванням. Починаючи з Python 3.6, jsonбібліотека автоматично декодує байт-коди з даними JSON за умови використання кодування UTF.
Мартін Пітерс

@ ManuelSchneid3r: В іншому випадку я рекомендую вам використовувати requestsбібліотеку, яка також автоматично виявляє правильний кодек UTF для використання у випадках, коли специфікація відсутня і в заголовку відповіді не вказано набір символів. Просто використовуйте response.json()метод.
Мартін Пітерс

35
import json
import urllib

url = 'http://example.com/file.json'
r = urllib.request.urlopen(url)
data = json.loads(r.read().decode(r.info().get_param('charset') or 'utf-8'))
print(data)

urllib , для Python 3.4
HTTPMessage , повернутого r.info ()


1
Суцільний код, відмінний від print dataнеправильного для Python 3. Має бути print(data).
Девід Меткалф,

1
Так і рядок 2 повинен бути import urllib.request. Крім того, цей файл .json в URL-адресі більше не існує.
hack-tramp

5
"""
Return JSON to webpage
Adding to wonderful answer by @Sanal
For Django 3.4
Adding a working url that returns a json (Source: http://www.jsontest.com/#echo)
"""

import json
import urllib

url = 'http://echo.jsontest.com/insert-key-here/insert-value-here/key/value'
respons = urllib.request.urlopen(url)
data = json.loads(respons.read().decode(respons.info().get_param('charset') or 'utf-8'))
return HttpResponse(json.dumps(data), content_type="application/json")

1
ух, що json.dumps () врятував мій день.
Ллойд,

У випадку з Django 1.7+, ви можете використовувати JsonResponse безпосередньо наступним чином from django.http import JsonResponse return JsonResponse({'key':'value'})
єнот

1
Я робив json.dump () замість json.dumps (), відчуваючи німоту, дякую за збереження!
Hashir Baig

4

Будьте обережні щодо перевірки та ін., Але прямим рішенням є таке:

import json
the_dict = json.load(response)


1

Стандартний бібліотечний модуль Python 3:

load(urlopen(url))

# imports (place these above the code before running it)
from json import load
from urllib.request import urlopen
url = 'https://jsonplaceholder.typicode.com/todos/1'

0

Хоча, мабуть, це вже дало відповідь, я хотів би додати до цього трохи

import json
import urllib2
class Website(object):
    def __init__(self,name):
        self.name = name 
    def dump(self):
     self.data= urllib2.urlopen(self.name)
     return self.data

    def convJSON(self):
         data=  json.load(self.dump())
     print data

domain = Website("https://example.com")
domain.convJSON()

Примітка: об’єкт, переданий json.load (), повинен підтримувати .read () , тому urllib2.urlopen (self.name) .read () не буде працювати. Переданий Доамін повинен бути забезпечений протоколом, у цьому випадку http


0

Ви також можете отримати json, використовуючи, requestsяк показано нижче:

import requests

r = requests.get('http://yoursite.com/your-json-pfile.json')
json_response = r.json()

0

Це ще одне простіше рішення вашого питання

pd.read_json(data)

де дані - це вихід str з наступного коду

response = urlopen("https://data.nasa.gov/resource/y77d-th95.json")
json_data = response.read().decode('utf-8', 'replace')

-1

Жоден із наведених прикладів тут не працював для мене. Вони були або для Python 2 (uurllib2), або для Python 3 повернули помилку "ImportError: No module named request". Я шукаю в Google повідомлення про помилку, і воно, очевидно, вимагає від мене встановлення модуля - що, очевидно, є неприйнятним для такого простого завдання.

Цей код працював для мене:

import json,urllib
data = urllib.urlopen("https://api.github.com/users?since=0").read()
d = json.loads(data)
print (d)

2
Ви, очевидно, використовуєте Python 2. У Python 3 немає urllib.urlopen; urlopenзнаходиться в urllib.requestмодулі.
Нік Маттео
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.