2011-10-24 35 views
23

Tôi đang cố gắng kiểm tra xem một từ nhất định có nằm trên một trang cho nhiều trang web hay không. Kịch bản chạy tốt để nói 15 trang web và sau đó nó dừng lại.codec utf8 không thể giải mã byte 0x96 trong python

UnicodeDecodeError: 'utf8' giải mã không thể giải mã byte 0x96 ở vị trí 15.344: start byte không hợp lệ

tôi đã tìm kiếm trên stackoverflow và tìm thấy nhiều vấn đề về nó nhưng tôi dường như không thể hiểu được những gì đã đi sai trong trường hợp của tôi.

Tôi muốn giải quyết hoặc nếu có lỗi bỏ qua trang web đó. Xin lời khuyên làm thế nào tôi có thể làm điều này như tôi mới và mã dưới đây chính nó đã đưa cho tôi một ngày để viết. Bằng cách này các trang web mà kịch bản dừng lại trên là http://www.homestead.com

filetocheck = open("bloglistforcommenting","r") 
resultfile = open("finalfile","w") 

for countofsites in filetocheck.readlines(): 
     sitename = countofsites.strip() 
     htmlfile = urllib.urlopen(sitename) 
     page = htmlfile.read().decode('utf8') 
     match = re.search("Enter your name", page) 
     if match: 
      print "match found : " + sitename 
      resultfile.write(sitename+"\n") 

     else: 
      print "sorry did not find the pattern " +sitename 

print "Finished Operations" 

Theo ý kiến ​​của Mark Tôi đã thay đổi mã để thực hiện BeautifulSoup

htmlfile = urllib.urlopen("http://www.homestead.com") 
page = BeautifulSoup((''.join(htmlfile))) 
print page.prettify() 

bây giờ tôi nhận được lỗi này

page = BeautifulSoup((''.join(htmlfile))) 
TypeError: 'module' object is not callable 

Tôi đang thử ví dụ bắt đầu nhanh của họ từ http://www.crummy.com/software/BeautifulSoup/documentation.html#Quick%20Start. Nếu tôi sao chép dán nó thì mã hoạt động tốt.

TÔI CUỐI CÙNG nó hoạt động. Cảm ơn mọi sự giúp đỡ của bạn. Đây là mã cuối cùng.

import urllib 
import re 
from BeautifulSoup import BeautifulSoup 

filetocheck = open("listfile","r") 

resultfile = open("finalfile","w") 
error ="for errors" 

for countofsites in filetocheck.readlines(): 
     sitename = countofsites.strip() 
     htmlfile = urllib.urlopen(sitename) 
     page = BeautifulSoup((''.join(htmlfile))) 
     pagetwo =str(page) 
     match = re.search("Enter YourName", pagetwo) 
     if match: 
      print "match found : " + sitename 
      resultfile.write(sitename+"\n") 

     else: 
      print "sorry did not find the pattern " +sitename 

print "Finished Operations" 

Trả lời

6

Nhiều trang web được mã hóa không chính xác. Để phân tích cú pháp HTML, hãy thử BeautifulSoup vì nó có thể xử lý nhiều loại HTML không chính xác được tìm thấy trong tự nhiên.

Beautiful Soup is a Python HTML/XML parser designed for quick turnaround projects like screen-scraping. Three features make it powerful:

  1. Beautiful Soup won't choke if you give it bad markup. It yields a parse tree that makes approximately as much sense as your original document. This is usually good enough to collect the data you need and run away.

  2. Beautiful Soup provides a few simple methods and Pythonic idioms for navigating, searching, and modifying a parse tree: a toolkit for dissecting a document and extracting what you need. You don't have to create a custom parser for each application.

  3. Beautiful Soup automatically converts incoming documents to Unicode and outgoing documents to UTF-8. You don't have to think about encodings, unless the document doesn't specify an encoding and Beautiful Soup can't autodetect one. Then you just have to specify the original encoding.

Mỏ nhấn mạnh.

+0

Tôi thay vì bỏ qua trang web này, tôi có thể làm như giải mã ('utf8', somecodeforerrortoskip) –

+0

user976847: Có rất nhiều lợi thế khác khi sử dụng BeautifulSoup. Tôi nghĩ bạn nên cho nó đi. –

+0

Tôi có một cái nhìn tại nó nhờ –

3

Các trang web 'http://www.homestead.com' không yêu cầu được gửi cho bạn utf-8, phản ứng thực sự tuyên bố là iso-8859-1:

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 

Bạn phải sử dụng mã hóa chính xác cho trang bạn thực sự nhận được, không chỉ ngẫu nhiên đoán.

+0

Điều là tôi có một danh sách lớn các trang web và đây chỉ là lần đầu tiên nhiều lỗi. Điều gì sẽ là cách tốt nhất để tôi chỉ cần bỏ qua một trang web nếu tôi tìm thấy một lỗi giải mã? –

+1

'charset = ISO-8859-1' là tương đương không gian mạng của" Cheque's in the mail ". –

22

byte tại 15344 là 0x96. Có lẽ tại vị trí 15343 có một mã hóa một byte của một ký tự hoặc byte cuối cùng của một mã hóa nhiều byte, làm cho 15344 bắt đầu một ký tự. 0x96 ở dạng nhị phân 10010110 và bất kỳ byte nào khớp với mẫu 10XXXXXX (0x80 đến 0xBF) chỉ có thể là byte thứ hai hoặc tiếp theo trong mã hóa UTF-8.

Do đó luồng không phải là UTF-8 hoặc các luồng khác bị hỏng.

Kiểm tra URI bạn liên kết đến, chúng tôi tìm thấy những tiêu đề:

Content-Type: text/html 

vì không có mã hóa nói, chúng ta nên sử dụng mặc định cho HTTP, đó là tiêu chuẩn ISO-8859-1 (aka "Latin 1 ").

Thẩm định nội dung, chúng tôi tìm dòng:

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 

Đó là một cơ chế giảm trở lại cho người dân là ai, vì một lý do, không có khả năng thiết lập các tiêu đề HTTP của họ một cách chính xác. Lần này chúng tôi được thông báo rõ ràng về mã hóa ký tự là ISO-8859-1.

Vì vậy, không có lý do gì để mong đợi đọc nó khi UTF-8 hoạt động.

Để có thêm niềm vui, khi chúng tôi xem xét trong ISO-8859-1 0x96 mã hóa U + 0096 là ký tự điều khiển "START OF GUARDED AREA", chúng tôi thấy rằng ISO-8859-1 không chính xác hoặc là . Có vẻ như những người tạo trang đã tạo ra một lỗi tương tự cho chính bạn.

Từ ngữ cảnh, có vẻ như chúng thực sự sử dụng Windows-1252, như mã hóa 0x96 mã hóa U + 2013 (EN-DASH, trông giống như ).

Vì vậy, để phân tích cú pháp trang cụ thể này mà bạn muốn giải mã trong Windows-1252.

Nói chung, bạn muốn kiểm tra tiêu đề khi chọn mã hóa ký tự, và có thể không chính xác trong trường hợp này (hoặc có thể không, nhiều hơn một vài codec "ISO-8859-1" thực sự là Windows-1252) , bạn sẽ sửa chữa thường xuyên hơn. Bạn vẫn cần phải có một cái gì đó bắt thất bại như thế này bằng cách đọc với một dự phòng. Phương thức decode lấy tham số thứ hai có tên là errors. Mặc định là 'strict', nhưng bạn cũng có thể có 'ignore', 'replace', 'xmlcharrefreplace' (không thích hợp), 'backslashreplace' (không thích hợp) và bạn có thể đăng ký trình xử lý dự phòng của riêng bạn với codecs.register_error().

+0

Để sửa nội dung Windows-1252 được nhúng trong utf-8, bạn có thể sử dụng ['bs4.UnicodeDammit.detwingle()'] (http://www.crummy.com/software/BeautifulSoup/bs4/doc/#inconsistent-encodings) – jfs

+0

Trong câu trả lời sâu, giải thích những gì lỗi (gần như chắc chắn) là. Thật không may là nó không thể hiểu được công cụ này mà không được ở cấp độ byte, trong đó tất nhiên, nhiều người không chuẩn bị để đi đến. Cảm ơn bạn đã đi thêm dặm :-) – Forbesmyester

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