Python urllib2: Nhận phản hồi JSON từ url


90

Tôi đang cố gắng NHẬN URL bằng Python và phản hồi là JSON. Tuy nhiên, khi tôi chạy

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

Html thuộc loại str và tôi đang mong đợi một JSON. Có cách nào tôi có thể nắm bắt phản hồi dưới dạng JSON hoặc từ điển python thay vì str không.


1
Có phải response.read()trả về một chuỗi JSON hợp lệ không?
Martijn Pieters

Có một chuỗi JSON hợp lệ của nó chỉ hoặc gõ str và không phải dict
Deepak B

Nếu đó là biểu diễn JSON của một chuỗi, chứ không phải là biểu diễn JSON của một đối tượng (dict), bạn không thể buộc máy chủ trả về cho bạn dữ liệu khác; bạn có thể cần đưa ra một yêu cầu khác. Nếu bạn không biết cách phân tích cú pháp biểu diễn JSON thành đối tượng Python tương đương, câu trả lời của Martjin Pieters là đúng.
abarnert 17/12/12

Câu trả lời:


183

Nếu URL đang trả về dữ liệu được mã hóa JSON hợp lệ, hãy sử dụng jsonthư viện để giải mã:

import urllib2
import json

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

1
@ ManuelSchneid3r: Câu trả lời ở đây là dành cho Python 2, nơi đọc từ responsecung cấp cho bạn các chuỗi bytest và json.load()mong đợi đọc một bytestring. JSON phải được mã hóa bằng codec UTF và các công cụ trên hoạt động cho UTF-8, UTF-16 và UTF-32, với điều kiện có mã BOM cho hai codec sau. Câu trả lời mà bạn liên kết đến giả định UTF-8 đã được sử dụng, câu trả lời này thường đúng vì đó là câu trả lời mặc định. Kể từ Python 3.6, jsonthư viện tự động giải mã các mã bytecodes với dữ liệu JSON cung cấp mã hóa UTF được sử dụng.
Martijn Pieters

@ ManuelSchneid3r: Nếu không, tôi khuyên bạn nên sử dụng requeststhư viện, thư viện này cũng tự động phát hiện codec UTF chính xác để sử dụng trong trường hợp thiếu BOM và không có tập ký tự nào được chỉ định trong tiêu đề phản hồi. Chỉ cần sử dụng response.json()phương pháp.
Martijn Pieters

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 , cho Python 3.4
HTTPMessage , trả về bởi r.info ()


1
Mã vững chắc khác với print datakhông chính xác cho Python 3. Nên print(data).
David Metcalfe

1
Có và dòng 2 nên được import urllib.request. Ngoài ra, tệp .json đó trong url không còn tồn tại.
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
whew, json.dumps () đó đã cứu một ngày của tôi.
Lloyd

Trong trường hợp Django 1.7 +, bạn có thể sử dụng JsonResponse trực tiếp như saufrom django.http import JsonResponse return JsonResponse({'key':'value'})
raccoon

1
Tôi đang thực hiện json.dump () thay vì json.dumps (), cảm thấy ngớ người, Cảm ơn bạn đã cứu!
Hashir Baig

4

Hãy cẩn thận về xác nhận và v.v., nhưng giải pháp đơn giản là sau:

import json
the_dict = json.load(response)

2
resource_url = 'http://localhost:8080/service/'
response = json.loads(urllib2.urlopen(resource_url).read())

1

Thư viện chuẩn Python 3 một lớp:

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

Mặc dù tôi đoán nó đã được trả lời, tôi muốn thêm một chút của tôi vào điều này

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()

Lưu ý: đối tượng được truyền tới json.load () phải hỗ trợ .read () , do đó urllib2.urlopen (self.name) .read () sẽ không hoạt động. Doamin được truyền phải được cung cấp giao thức trong trường hợp này là http


0

bạn cũng có thể nhận json bằng cách sử dụng requestsnhư sau:

import requests

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

0

Đây là một giải pháp khác đơn giản hơn cho câu hỏi của bạn

pd.read_json(data)

trong đó dữ liệu là đầu ra str từ đoạn mã sau

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

-1

Không có ví dụ nào được cung cấp ở đây phù hợp với tôi. Chúng dành cho Python 2 (uurllib2) hoặc dành cho Python 3 trả về lỗi "ImportError: No module name request". Tôi google thông báo lỗi và nó rõ ràng yêu cầu tôi cài đặt một mô-đun - điều này rõ ràng là không thể chấp nhận được đối với một nhiệm vụ đơn giản như vậy.

Mã này phù hợp với tôi:

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

2
Rõ ràng là bạn đang sử dụng Python 2. Trong Python 3, không có urllib.urlopen; urlopennằm trong urllib.requestmô-đun.
Nick Matteo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.