2012-06-16 38 views
8

Tôi gặp sự cố này khi cố gắng lấy tất cả các nút văn bản trong tài liệu HTML bằng lxml nhưng tôi nhận được UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128). Tuy nhiên, khi tôi cố gắng tìm ra loại mã hóa của trang này (encoding = chardet.detect(response)['encoding']), nó nói nó là utf-8. Có vẻ lạ khi một trang đơn có utf-8 và ascii. Trên thực tế, điều này:UnicodeEncodeError khi tìm nạp url

fromstring(response).text_content().encode('ascii', 'replace') 

giải quyết vấn đề.

Ở đây nó là mã của tôi:

from lxml.html import fromstring 
import urllib2 
import chardet 
request = urllib2.Request(my_url) 
request.add_header('User-Agent', 
        'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)') 
request.add_header("Accept-Language", "en-us") 
response = urllib2.urlopen(request).read() 

print encoding 
print fromstring(response).text_content() 

Output:

utf-8 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 8995: ordinal not in range(128) 

Tôi có thể làm gì để giải quyết vấn đề này ?. Hãy nhớ rằng tôi muốn làm điều này với một vài trang khác, vì vậy tôi không muốn mã hóa trên cơ sở cá nhân.

UPDATE:

Có thể có cái gì khác xảy ra ở đây. Khi tôi chạy kịch bản này trên thiết bị đầu cuối, tôi nhận được một đầu ra chính xác nhưng khi chạy nó bên trong SublimeText, tôi nhận được UnicodeEncodeError ... ¿?

UPDATE2:

Nó cũng đang xảy ra khi tôi tạo ra một tập tin với sản lượng này. .encode('ascii', 'replace') đang hoạt động nhưng tôi muốn có giải pháp tổng quát hơn.

Trân

+1

Có 'in u" \ u00A9 "' bên trong tập lệnh của bạn cũng tạo ra lỗi không? – jfs

+0

Có.UnicodeEncodeError: 'ascii' codec không thể mã hóa ký tự u '\ xa9' ở vị trí 0: thứ tự không nằm trong phạm vi (128) :-) –

+0

bạn có thể đặt PYTHONIOENCODING thành bất kỳ ký tự mã hóa nào SublimeText chấp nhận. – jfs

Trả lời

5

Bạn có thể thử gói chuỗi bằng repr() không? This article có thể hữu ích.

print repr(fromstring(response).text_content()) 
+0

Điều này làm việc tốt trong văn bản tuyệt vời và cũng trong thiết bị đầu cuối. Tôi đoán đây là một cách giải quyết. Cảm ơn! –

0

Dựa trên bản cập nhật đầu tiên của bạn, tôi sẽ nói rằng nhà ga nói với Python để đầu ra utf-8 và SublimeText làm rõ dự kiến ​​ascii. Vì vậy, tôi nghĩ rằng giải pháp sẽ được trong việc tìm kiếm các thiết lập đúng trong SublimeText.

Tuy nhiên, nếu bạn không thể thay đổi nội dung SublimeText, bạn nên sử dụng chức năng encode như bạn đã làm trong một chức năng riêng biệt.

def smartprint(text) : 
    if sys.stdout.encoding == None : 
     print text 
    else : 
     print text.encode(sys.stdout.encoding , 'replace') 

Bạn có thể sử dụng chức năng này thay vì print. Hãy nhớ rằng đầu ra của chương trình của bạn khi chạy trong SublimeText khác với Terminal. Do các ký tự có dấu trọng âm replace sẽ mất dấu khi mã này được chạy trong SublimeText, ví dụ: é sẽ được hiển thị là e.

3

Theo như viết ra vào một tập tin như đã nói trong chỉnh sửa của bạn, tôi sẽ khuyên bạn nên mở file với codec mô-đun:

import codecs 
output_file = codecs.open('filename.txt','w','utf8') 

Tôi không biết SublimeText, nhưng nó có vẻ đang cố gắng đọc đầu ra của bạn dưới dạng ASCII, do đó lỗi mã hóa.

+0

Đang hoạt động. Cảm ơn! –

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