2013-07-28 46 views
46

tôi nhận được một lỗi với patter sau:u ' ufeff' bằng Python chuỗi

UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128) 

Không chắc u'\ufeff' là gì, nó xuất hiện khi tôi scraping web. Làm thế nào tôi có thể khắc phục tình hình? Phương thức chuỗi .replace() không hoạt động trên đó.

+5

Đầu vào này đến từ đâu? Bạn đang cố gắng làm gì? Vui lòng bao gồm mã Python của bạn. –

+1

Ngẫu nhiên, tôi thấy rằng .replace() không hoạt động trong python hiện đại nếu tôi nhớ chỉ báo unicode: s.replace (u '\ ufeff', '') –

+0

@DougBradshaw khi bạn nói "python hiện đại", ý bạn là , 2.7+ hoặc 3.0+? – teewuane

Trả lời

78

Ký tự Unicode U+FEFF là dấu thứ tự byte hoặc BOM và được sử dụng để cho biết sự khác biệt giữa mã hóa UTF-16 lớn và nhỏ. Nếu bạn giải mã trang web bằng codec thích hợp, Python sẽ xóa nó cho bạn. Ví dụ:

#!python2 
#coding: utf8 
u = u'ABC' 
e8 = u.encode('utf-8')  # encode without BOM 
e8s = u.encode('utf-8-sig') # encode with BOM 
e16 = u.encode('utf-16')  # encode with BOM 
e16le = u.encode('utf-16le') # encode without BOM 
e16be = u.encode('utf-16be') # encode without BOM 
print 'utf-8  %r' % e8 
print 'utf-8-sig %r' % e8s 
print 'utf-16 %r' % e16 
print 'utf-16le %r' % e16le 
print 'utf-16be %r' % e16be 
print 
print 'utf-8 w/ BOM decoded with utf-8  %r' % e8s.decode('utf-8') 
print 'utf-8 w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig') 
print 'utf-16 w/ BOM decoded with utf-16 %r' % e16.decode('utf-16') 
print 'utf-16 w/ BOM decoded with utf-16le %r' % e16.decode('utf-16le') 

Lưu ý rằng EF BB BF là một bảng mã UTF-8. Nó không cần thiết cho UTF-8, nhưng chỉ phục vụ như một chữ ký (thường là trên Windows).

Output:

utf-8  'ABC' 
utf-8-sig '\xef\xbb\xbfABC' 
utf-16 '\xff\xfeA\x00B\x00C\x00' # Adds BOM and encodes using native processor endian-ness. 
utf-16le 'A\x00B\x00C\x00' 
utf-16be '\x00A\x00B\x00C' 

utf-8 w/ BOM decoded with utf-8  u'\ufeffABC' # doesn't remove BOM if present. 
utf-8 w/ BOM decoded with utf-8-sig u'ABC'   # removes BOM if present. 
utf-16 w/ BOM decoded with utf-16 u'ABC'   # *requires* BOM to be present. 
utf-16 w/ BOM decoded with utf-16le u'\ufeffABC' # doesn't remove BOM if present. 

Lưu ý rằng utf-16đòi hỏi BOM có mặt, hoặc Python sẽ không biết nếu dữ liệu là big- hoặc về cuối nhỏ.

2

Nhân vật đó là BOM hoặc "Dấu đơn hàng". Nó thường được nhận như là một vài byte đầu tiên của một tệp, cho bạn biết cách giải thích mã hóa phần còn lại của dữ liệu. Bạn có thể chỉ cần loại bỏ các ký tự để tiếp tục. Mặc dù, kể từ khi lỗi nói rằng bạn đang cố gắng chuyển đổi thành 'ascii', bạn có thể chọn mã hóa khác cho bất kỳ điều gì bạn đang cố gắng thực hiện.

-1

Cụ thể, Dấu thứ tự byte của feff là chỉ báo về mã hóa utf-16. Vì tất cả các byte của utf-16 hiếm khi được sử dụng, có hai lược đồ mã hóa khác nhau mà mọi người sử dụng. Vì các mã hóa khác nhau về cơ bản chỉ lật các byte trong tiêu chuẩn utf-16 là Dấu thứ tự Byte sẽ luôn là feff. Bằng cách đó, nếu ai đó gửi một thứ gì đó bằng Dấu thứ tự byte của ffef, bộ mã hóa unicode biết lật thứ tự của tất cả các byte trong tài liệu sau.

+0

'UTF-16' có hai mã hóa khác nhau: nhỏ gọn và lớn. Dấu thứ tự byte được sử dụng để cho biết sự khác biệt. –

+2

Bạn đang mô tả UTF-16. "Thứ tự byte" là * không liên quan * trong utf-8, bởi vì theo định nghĩa, nó chỉ sử dụng mã 8 bit. Vì vậy FEFFh không bao giờ có thể là một mã UTF-8 hợp lệ. Biểu diễn 8 bit * của nó có thể (dài 3 byte), nhưng chỉ sau khi được phân tích cú pháp thành các ký tự Unicode. Và sau đó bạn không còn quan tâm đến thứ gì đó cấp thấp như "sắp xếp byte". Tìm 0FEFFh (được mã hóa bằng UTF8) ở đầu tệp UTF-8 hợp lệ khác có thể là lỗi mã hóa và có thể bỏ qua một cách an toàn. – usr2564301

4

Nội dung bạn đang cào được mã hóa bằng unicode thay vì văn bản ascii và bạn nhận được một ký tự không chuyển đổi thành ascii. Quyền 'dịch' phụ thuộc vào trang web ban đầu được cho là như thế nào. Python's unicode page cung cấp thông tin cơ bản về cách hoạt động của nó.

Bạn đang cố gắng in kết quả hoặc dán nó vào một tệp? Lỗi cho thấy đó là viết dữ liệu gây ra sự cố, chứ không phải đọc nó. This question là một nơi tốt để tìm các bản sửa lỗi.

1

Vấn đề này phát sinh cơ bản khi bạn lưu mã python của bạn trong một UTF-8 hoặc UTF-16 mã hóa vì python thêm một số ký tự đặc biệt vào đầu của mã tự động (mà không được hiển thị bởi các biên tập viên văn bản) để xác định định dạng mã hóa. Nhưng, khi bạn cố gắng thực thi mã, nó cung cấp cho bạn lỗi cú pháp trong dòng 1, bắt đầu mã bởi vì trình biên dịch python hiểu mã hóa ASCII. khi bạn xem mã của tệp bằng cách sử dụng hàm đọc() bạn có thể thấy ở đầu mã trả về '\ ufeff' được hiển thị. Giải pháp đơn giản nhất cho vấn đề này chỉ bằng cách thay đổi mã hóa trở lại mã hóa ASCII (để bạn có thể sao chép mã của mình vào một notepad và lưu nó, hãy nhớ! Hãy chọn mã ASCII ... Hy vọng điều này sẽ hữu ích.

0

Tôi đã thực hiện điều này trên Python 3 và tìm thấy câu hỏi này (và solution). Khi mở tệp, Python 3 hỗ trợ từ khóa mã hóa để tự động xử lý mã hóa.

Nếu không có nó, HÐQT được bao gồm trong các kết quả đọc:

>>> f = open('file', mode='r') 
>>> f.read() 
'\ufefftest' 

Giving mã hóa chính xác, BOM được bỏ qua trong kết quả:

>>> f = open('file', mode='r', encoding='utf-8-sig') 
>>> f.read() 
'test' 

Chỉ cần tôi 2 xu.

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