2011-02-06 36 views
64

Vì vậy, tôi đã dành nhiều thời gian cho việc này, và có vẻ như với tôi như nó phải là một sửa chữa đơn giản. Tôi đang cố gắng sử dụng Xác thực của Facebook để đăng ký người dùng trên trang web của mình và tôi đang cố gắng thực hiện phía máy chủ. Tôi đã nhận được đến điểm mà tôi nhận mã thông báo truy cập của tôi, và khi tôi đi đến:String to Dictionary in Python

https://graph.facebook.com/me?access_token=MY_ACCESS_TOKEN

tôi nhận được thông tin mà tôi đang tìm kiếm như là một chuỗi đó là như thế này:

{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}

Nó có vẻ như tôi chỉ cần có thể sử dụng dict(string) về vấn đề này nhưng tôi nhận được lỗi này:

ValueError: dictionary update sequence element #0 has length 1; 2 is required

Vì vậy, tôi cố gắng sử dụng Pickle, nhưng có err này hoặc:

KeyError: '{'

Tôi đã thử sử dụng django.serializers để hủy tuần tự hóa nhưng có kết quả tương tự. Có suy nghĩ gì không? Tôi cảm thấy câu trả lời phải đơn giản, và tôi chỉ là ngu ngốc. Cảm ơn vì bất kì sự giúp đỡ!

+0

Nếu bạn muốn đánh giá chuỗi là Python, bạn có thể cần thay đổi chuỗi: '" verified ": true' không thành công trừ khi' true' được xác định. Hoặc bạn có thể sử dụng '" verified ": True' hoặc' "verified": "true" '. –

+2

@Matt: Tôi nghi ngờ anh ta có thể thay đổi định dạng đầu ra của graph.facebook.com. –

+0

@Fred: Với tiêu đề của câu hỏi ("String to Dictionary in Python"), tôi đoán anh ta có thể thay đổi nó từ Python trước khi anh ta gọi 'ast.literal_eval()'. Câu trả lời của bạn (sửa đổi) là đúng, mặc dù - một deserializer JSON là một giải pháp tốt hơn. –

Trả lời

132

Dữ liệu này là JSON! Bạn có thể deserialize nó bằng cách sử dụng được xây dựng trong json module nếu bạn đang ở trên Python 2.6+, nếu không bạn có thể sử dụng bên thứ ba tuyệt vời simplejson module.

import json # or `import simplejson as json` if on Python < 2.6 

json_string = u'{ "id":"123456789", ... }' 
obj = json.loads(json_string) # obj now contains a dict of the data 
+2

Tại sao bạn đặt 'u' trước chuỗi JSON mẫu? –

+2

@John: Nó biểu thị [chuỗi Unicode] (http://docs.python.org/howto/unicode.html#the-unicode-type). Tôi đặt nó chủ yếu là hết thói quen, nhưng có lẽ Facebook API có thể trả lại dữ liệu với các ký tự không phải ASCII trong đó; trong trường hợp đó, dữ liệu sẽ được mã hóa (có thể là UTF-8), và 'decode()' -ing nó sẽ tạo ra một chuỗi 'unicode' - đó là những gì tôi đã sử dụng trong ví dụ của mình. Ngoài ra, [trang này] (http://www.json.org/fatfree.html) đề cập đến JSON luôn ở dạng Unicode (tìm kiếm cụm từ, đó là khoảng nửa chừng) – Cameron

+2

Nó chỉ ra một chữ nhỏ unicode trong Python. Thói quen không phải là một lý do chính đáng. "Mã hóa ký tự của văn bản JSON luôn là Unicode." - [Uu] nicode KHÔNG phải là mã hóa. Những gì json.loads() mong đợi là những gì bạn đã có "trên dây" mà thường là một đối tượng str mã hóa trong ASCII. Trường hợp duy nhất mà bạn sẽ cho json.loads() một đối tượng unicode cố tình là nơi mà một số người lạ đã truyền nó trong UTF-16 và như được ghi lại, bạn cần phải tự giải mã nó. –

13

Sử dụng ast.literal_eval để đánh giá các chữ cái Python. Tuy nhiên, những gì bạn có là JSON (lưu ý "true" chẳng hạn), vì vậy hãy sử dụng trình khử giải JSON.

>>> import json 
>>> s = """{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}""" 
>>> json.loads(s) 
{u'first_name': u'John', u'last_name': u'Doe', u'verified': True, u'name': u'John Doe', u'locale': u'en_US', u'gender': u'male', u'email': u'[email protected]', u'link': u'http://www.facebook.com/jdoe', u'timezone': -7, u'updated_time': u'2011-01-12T02:43:35+0000', u'id': u'123456789'} 
Các vấn đề liên quan