2013-11-25 16 views
16

Tôi đang chạy chương trình Python tìm nạp trang web được mã hóa UTF-8 và tôi trích xuất một số văn bản từ HTML bằng cách sử dụng BeautifulSoup.Cách phân tích cú pháp HTML được mã hóa UTF-8 thành chuỗi Unicode với BeautifulSoup một cách chính xác?

Tuy nhiên, khi tôi viết văn bản này vào một tệp (hoặc in nó trên bảng điều khiển), nó được viết bằng mã hóa không mong muốn.

chương trình mẫu:

import urllib2 
from BeautifulSoup import BeautifulSoup 

# Fetch URL 
url = 'http://www.voxnow.de/' 
request = urllib2.Request(url) 
request.add_header('Accept-Encoding', 'utf-8') 

# Response has UTF-8 charset header, 
# and HTML body which is UTF-8 encoded 
response = urllib2.urlopen(request) 

# Parse with BeautifulSoup 
soup = BeautifulSoup(response) 

# Print title attribute of a <div> which uses umlauts (e.g. können) 
print repr(soup.find('div', id='navbutton_account')['title']) 

Chạy điều này mang lại kết quả:

# u'Hier k\u0102\u015bnnen Sie sich kostenlos registrieren und/oder einloggen!' 

Nhưng tôi mong chờ một chuỗi Python Unicode để render ö trong từ können như \xf6:

# u'Hier k\xf6bnnen Sie sich kostenlos registrieren und/oder einloggen!' 

Tôi đã thử truyền 'từ Tham số mã hóa 'thành BeautifulSoup và cố gắng read()decode() đối tượng response, nhưng nó không tạo sự khác biệt hoặc ném lỗi.

Với lệnh curl www.voxnow.de | hexdump -C, tôi có thể thấy rằng các trang web thực sự là UTF-8 mã hóa (tức là nó chứa 0xc3 0xb6) cho ö nhân vật:

 20 74 69 74 6c 65 3d 22 48 69 65 72 20 6b c3 b6 | title="Hier k..| 
     6e 6e 65 6e 20 53 69 65 20 73 69 63 68 20 6b 6f |nnen Sie sich ko| 
     73 74 65 6e 6c 6f 73 20 72 65 67 69 73 74 72 69 |stenlos registri| 

tôi vượt quá giới hạn của khả năng Python của tôi , vì vậy tôi đang thua lỗ về cách gỡ lỗi thêm nữa. Lời khuyên nào?

+0

Strange .. như '\ u0102 \ u015b 'is' 'Ă''' .. – aIKid

+2

Đây có phải là một bản sao của câu hỏi này không: http://stackoverflow.com/questions/7219361/python-and-beautifulsoup-encoding-issues?rq=1 – justhalf

+0

@justhalf Tôi nghĩ rằng tôi đã thấy câu hỏi đó, nhưng không nghĩ rằng tôi có cùng kết quả. Nhưng tôi sẽ kiểm tra lại, cảm ơn. –

Trả lời

19

Như justhalf chỉ ra ở trên, câu hỏi của tôi ở đây thực chất là một bản sao của this question.

Nội dung HTML được báo cáo là UTF-8 được mã hóa và, phần lớn là, ngoại trừ một hoặc hai ký tự UTF-8 không hợp lệ.

này dường như lẫn lộn BeautifulSoup về mà mã hóa được sử dụng, và khi cố gắng giải mã đầu tiên là UTF-8 khi đi qua các nội dung để BeautifulSoup như này:

soup = BeautifulSoup(response.read().decode('utf-8')) 

tôi sẽ nhận được lỗi:

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 186812-186813: 
        invalid continuation byte 

Nhìn kỹ hơn ở đầu ra, đã có trường hợp của ký tự Ü được mã hóa sai là chuỗi byte không hợp lệ 0xe3 0x9c, thay vì đúng 0xc3 0x9c.

Khi hiện highest-rated answer về câu hỏi mà đề nghị, UTF-8 ký tự không hợp lệ có thể được loại bỏ trong khi phân tích, do đó chỉ có dữ liệu hợp lệ được thông qua với BeautifulSoup:

soup = BeautifulSoup(response.read().decode('utf-8', 'ignore')) 
3

Encoding kết quả để utf-8 dường như làm việc cho tôi:

print (soup.find('div', id='navbutton_account')['title']).encode('utf-8') 

Nó mang lại:

Hier können Sie sich kostenlos registrieren und/oder einloggen! 
+0

Hmm .. Tôi đã thử trên một vài máy (với Python 2.7.3); mã đó cho tôi bốn byte thay cho hai ký tự bạn nhận được cho ký tự 'ö':' c4 82 c5 9b' –

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