Chuỗi vào từ điển bằng Python


126

Vì vậy, tôi đã dành nhiều thời gian cho việc này, và có vẻ như đối với tôi nó phải là một bản sửa lỗi đơ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 việc đó ở phía máy chủ. Tôi đã đến thời điểm nhận được mã thông báo truy cập của mình và khi tôi truy cập:

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 dưới dạng một chuỗi 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"}

Có vẻ như tôi chỉ có thể sử dụng dict(string)trên này nhưng tôi gặp lỗi này:

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

Vì vậy, tôi đã thử sử dụng Pickle, nhưng gặp lỗi này:

KeyError: '{'

Tôi đã thử sử dụng django.serializersđể hủy tuần tự hóa nó 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 thật ngu ngốc. Cảm ơn vì bất kì sự giúp đỡ!


Nếu bạn muốn đánh giá chuỗi là Python, bạn có thể cần phải thay đổi chuỗi của mình: "verified":truekhô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".
Matt Curtis

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

@Fred: Với tiêu đề của câu hỏi ("Chuỗi thành từ điển trong Python"), tôi đoán anh ấy có thể thay đổi nó từ Python trước khi anh ấy gọi ast.literal_eval(). Tuy nhiên, câu trả lời (đã sửa đổi) của bạn là đúng - bộ giải mã JSON là giải pháp tốt hơn.
Matt Curtis

1
@MattCurtis: Thay đổi điều đó một cách mạnh mẽ (trước ast.literal_eval) sẽ yêu cầu phân tích cú pháp nó thành JSON ngay từ đầu. Tôi đã đề cập đến ast.literal_eval là cách chính xác để thực hiện những gì OP đã cố gắng làm với dict (some_string).
Fred Nurk

@Fred: Tôi nghĩ rằng chúng tôi đang đồng ý đồng ý :-)
Matt Curtis

Câu trả lời:


239

Dữ liệu này là JSON ! Bạn có thể giải mã hóa nó bằng cách sử dụng jsonmô-đun tích hợp sẵn nếu bạn đang sử dụng Python 2.6+, nếu không, bạn có thể sử dụng simplejsonmô-đun tuyệt vời của bên thứ ba .

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

5
Tại sao bạn lại đặt utrước chuỗi JSON mẫu của mình?
John Machin

2
@John: Nó chỉ ra một chuỗi Unicode . Tôi đặt nó hầu hết chỉ là do thói quen, nhưng có lẽ API Facebook 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ẽ mang lại một unicodechuỗi - đó là những gì tôi đã sử dụng trong ví dụ của mình. Ngoài ra, trang này đề cập đến JSON luôn ở trong bảng mã Unicode (tìm kiếm cụm từ, nó đang ở khoảng nửa chừng)
Cameron

3
Nó chỉ ra một chữ unicode nhỏ 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ó "over the wire", thường là một đối tượng str được mã hóa bằng ASCII. Trường hợp duy nhất mà bạn cố tình cung cấp cho json.loads () một đối tượng unicode là khi một người lạ nào đó đã truyền nó trong UTF-16 và như đã được ghi nhận, bạn cần phải tự giải mã nó.
John Machin

1
@John: Vâng, small-u unicodelà kiểu Python, chứa một chuỗi Unicode (danh từ riêng big-U). Tôi cũng đồng ý rằng Unicode hoàn toàn không phải là một bảng mã, vì vậy có lẽ tôi không nên trỏ đến trang đó như một tài liệu tham khảo. Tuy nhiên, không có lý do gì để tránh chuyển các unicodechuỗi tới json.loads- các tài liệu nói rõ rằng điều này hoàn toàn có thể chấp nhận được và tôi thích sử dụng một chuỗi được giải mã trước vì nó rõ ràng hơn.
Cameron

8
@ John: Xin lỗi là gàn dở, nhưng json.loads()không mong đợi một strđối tượng được mã hóa trong ASCII - dự kiến hoặc là một strđối tượng được mã hóa trong UTF-8 hoặc một unicodeđối tượng (hoặc một strđối tượng cộng với một mã hóa rõ ràng)
Cameron

19

Sử dụng ast.literal_eval để đánh giá các ký tự Python. Tuy nhiên, những gì bạn có là JSON (lưu ý là "true" chẳng hạn), vì vậy hãy sử dụng bộ giải mã 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'jdoe@gmail.com', 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'}
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.