2013-08-27 20 views
9

Là dự án giúp tôi tìm hiểu Python, tôi đang tạo một trình xem CMD của Reddit bằng cách sử dụng dữ liệu json (ví dụ: www.reddit.com/all/ .json). Khi một số bài đăng hiển thị và tôi cố gắng in chúng (đó là những gì tôi giả định là gây ra lỗi), tôi nhận được lỗi này:Không thể in ký tự ' u2019' bằng Python từ đối tượng JSON

Traceback (cuộc gọi gần đây nhất): Tệp "C: \ Users \ nsaba \ Desktop \ reddit_viewer.py ", dòng 33, in in ("% d. (% d)% s \ n "% (i + 1, obj ['dữ liệu'] ['điểm'], obj ['dữ liệu'] [ 'title']))

file "C: \ Python33 \ lib \ mã hóa \ cp437.py", dòng 19, trong mã hóa trở codecs.charmap_encode (đầu vào, self.errors, encoding_map) [0] UnicodeEncodeError: codec 'charmap' không thể mã hóa ký tự '\ u2019' ở vị trí 32: bản đồ ký tự thành

Đây là nơi tôi xử lý các dữ liệu:

request = urllib.request.urlopen(url) 
content = request.read().decode('utf-8') 
jstuff = json.loads(content) 

Dòng Tôi sử dụng để in các dữ liệu được liệt kê trong các lỗi trên:

print ("%d. (%d) %s\n" % (i+1, obj['data']['score'], obj['data']['title'])) 

bất cứ ai có thể đề xuất, nơi tôi có thể đi sai?

+0

Vấn đề gần như chắc chắn không liên quan gì đến JSON, hoặc với bất kỳ thứ gì khác trong mã của bạn. Hãy thử chỉ 'in ('\ u2019')' và xem bạn có gặp lỗi tương tự không. Nếu vậy, vấn đề là thiết bị đầu cuối của bạn ("hộp DOS") không được thiết lập để làm đầu ra Unicode đúng cách, và đó là những gì bạn cần phải sửa chữa. – abarnert

+0

Có bạn đã đúng. Lý do cho dữ liệu bổ sung là vì tôi đã học hỏi các câu hỏi được cung cấp thông tin mà tôi có, và không phải về những gì tôi nghĩ là có thể. –

+1

Nhưng bạn nên đăng ví dụ hoàn chỉnh tối thiểu thể hiện vấn đề của bạn. Đó là những gì một [SSCCE] (http://sscce.org) là tất cả về. Nếu 'in ('\ u2019')' là đủ để chứng minh điều đó, thì bất kỳ ví dụ phức tạp nào khác cũng sẽ chỉ dẫn mọi người vào những cuộc săn ngỗng hoang dã. Nếu bạn lo lắng mọi người có thể hỏi "Tại sao bạn muốn in ký tự đó?", Thì bạn có thể thêm ngữ cảnh giải thích nó ... nhưng vẫn còn, dẫn đến vấn đề thực tế. – abarnert

Trả lời

18

Đó là gần như chắc chắn rằng bạn có vấn đề không có gì để làm với mã bạn đã thể hiện, và có thể được sao chép trong một dòng:

print(u'\2019') 

Nếu bộ ký tự của thiết bị đầu cuối của bạn không thể xử lý U + 2019 (hoặc nếu Python bị nhầm lẫn về những gì ký tự đặt thiết bị đầu cuối của bạn sử dụng), không có cách nào để in nó ra. Nó không quan trọng cho dù nó đến từ JSON hay bất cứ nơi nào khác.

Thiết bị đầu cuối Windows (aka "DOS prompt" hoặc "cmd window") thường được định cấu hình cho một bộ ký tự như cp1252 chỉ biết về 256 trong số 110000 ký tự và không có gì Python có thể thực hiện việc này mà không có thay đổi lớn để triển khai ngôn ngữ. *

Xem PrintFails trên Python Wiki để biết chi tiết, giải pháp và liên kết đến thông tin khác. Ngoài ra còn có một vài trăm dups của vấn đề này trên SO (mặc dù nhiều người trong số họ sẽ được cụ thể cho Python 2.x, mà không đề cập đến nó).


* Windows có một bộ toàn bộ riêng biệt của các API để in UTF-16 để các thiết bị đầu cuối, vì vậy Python có thể phát hiện stdout đó là một thiết bị đầu cuối Windows, và nếu như vậy mã hóa sang UTF-16 và sử dụng các API đặc biệt thay vì mã hóa vào bộ ký tự của thiết bị đầu cuối và sử dụng bộ mã chuẩn. Nhưng điều này làm nảy sinh nhiều vấn đề khác nhau (ví dụ: các cách in khác nhau để stdout không đồng bộ). Đã có cuộc thảo luận về việc thực hiện những thay đổi này, nhưng ngay cả khi tất cả mọi người đã đồng ý và bản vá được viết vào ngày mai, nó vẫn sẽ không giúp bạn cho đến khi bạn nâng cấp lên bất kỳ phiên bản Python tương lai nào được thêm vào…

+0

Xin lỗi vì sự lừa đảo. Tôi sẽ xem xét các tài nguyên bạn đã cung cấp. –

+3

@ N-Saba: À, thật khó để biết đây là một sự lừa đảo, bởi vì nó không thực sự rõ ràng những gì bạn nên tìm kiếm cho đến khi bạn đã biết ít nhất một nửa câu trả lời… – abarnert

+0

@ N-Saba, tôi biết đây là một thread, nhưng bạn nên đánh dấu điều này là câu trả lời nếu nó trả lời câu hỏi của bạn (nó đã khai thác) – ivan7707

0

Tôi đặt IDLE (Python Shell) và phông chữ mặc định CMD của Window tới Bảng điều khiển Lucida (phông chữ được hỗ trợ utf-8) và các loại lỗi này đã biến mất; và bạn không còn thấy hộp [] [] [] [] [] [] [] []

:)

0

@ N-Saba, những gì là chuỗi gây ra lỗi được ném? Trong trường hợp thử nghiệm của tôi, đây có vẻ là một lỗi phiên bản cụ thể trong python 2.7.3.

Trong thức ăn tôi đã phân tích, những "danh hiệu" lĩnh vực có giá trị sau:

u'title': u'Intel\u2019s Sharp-Eyed Social Scientist' 

tôi nhận được dự kiến ​​ngay trích dẫn đơn char khi tôi gọi một trong những, trong python 2.7.6 .

python -c "print {u'title': u'Intel\u2019s Sharp-Eyed Social Scientist'}['title']" 
Intel’s Sharp-Eyed Social Scientist 

Trong 2.7.3, tôi nhận được lỗi, trừ khi tôi mã hóa các giá trị mà tôi kéo bởi KeyName.

print {u'title': u'Intel\u2019s Sharp-Eyed Social Scientist'}['title'] 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 5: ordinal not in range(128) 
print {u'title': u'Intel\u2019s Sharp-Eyed Social Scientist'}['title'].encode('utf-8', 'replace') 
Intel’s Sharp-Eyed Social Scientist 

fwiw, @abamert lệnh in ('\ u2019') in "9". Tôi nghĩ rằng mã dự kiến ​​đã được in (u '\ u2019').

+0

'u' không bắt buộc đối với Python 3, vì nó mặc định là Unicode. – leewz

+0

Tôi gặp lỗi này trong 2.7.6 – user1167442

0

Tôi gặp phải lỗi tương tự khi cố gắng viết đầu ra JSON API vào tệp .cav qua pd.DataFrame.to_csv() trên cài đặt Win của Python 2.7.14.

Xác định mã hóa như utf-8 cố định quá trình của tôi:

pd.DataFrame.to_csv(filename, encoding='utf-8') 
0

Đối với bất cứ ai gặp phải này trong hệ điều hành MacOS, câu trả lời @ abarnert là chính xác và tôi đã có thể sửa chữa nó bằng cách đặt này ở phía trên cùng của tập tin nguồn vi phạm : -

# magic to make everything work in Unicode 
import sys 
reload(sys) 
sys.setdefaultencoding('utf-8') 

Để làm rõ, điều này đảm bảo đầu ra đầu cuối chấp nhận Unicode chính xác.

Các vấn đề liên quan