utf8编解码器无法解码python中的字节0x96

时间:2011-10-24 09:26:29

标签: python

我正在尝试检查许多网站的网页上是否有某个字词。该脚本可以运行15个站点,然后停止。

UnicodeDecodeError:'utf8'编解码器无法解码位置15344中的字节0x96:无效的起始字节

我对stackoverflow进行了搜索并发现了很多问题,但我似乎无法理解我的情况出了什么问题。

我想要解决它,或者如果有错误跳过该网站。请告诉我如何做到这一点,因为我是新手,下面的代码本身花了我一天的时间来写。顺便说一句,脚本暂停的网站是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"

根据Mark的评论,我更改了代码以实现beautifulsoup

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

现在我收到此错误

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

我正在尝试http://www.crummy.com/software/BeautifulSoup/documentation.html#Quick%20Start的快速启动示例。如果我复制粘贴它,那么代码工作正常。

我终于开始工作了。感谢大家的帮助。这是最终的代码。

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"

3 个答案:

答案 0 :(得分:25)

15344处的字节为0x96。据推测,在位置15343处,存在字符的单字节编码或多字节编码的最后一个字节,使得15344成为字符的开始。 0x96是二进制10010110,与模式10XXXXXX(0x80到0xBF)匹配的任何字节只能是UTF-8编码中的第二个或后续字节。

因此,流不是UTF-8,否则会损坏。

检查您链接的URI,我们找到标题:

Content-Type: text/html

由于没有声明编码,我们应该使用HTTP的默认值,即ISO-8859-1(又名“Latin 1”)。

检查我们找到的内容:

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

对于因某些原因无法正确设置HTTP标题的人而言,这是一种后备机制。这次我们被明确告知字符编码是ISO-8859-1。

因此,没有理由期望将其作为UTF-8工作。

为了获得额外的乐趣,当我们考虑在ISO-8859-1 0x96中编码U + 0096这是控制字符“START OF GUARDED AREA”时,我们发现 ISO-8859-1也不正确即可。创建页面的人似乎对自己造成了类似的错误。

从上下文来看,似乎他们实际上使用的是Windows-1252,因为编码0x96编码U + 2013(EN-DASH,看起来像)。

因此,要解析您希望在Windows-1252中解码的特定页面。

更一般地说,你想在选择字符编码时检查标题,虽然在这种情况下它可能是不正确的(或者可能不是,但是多个“ISO-8859-1”编解码器实际上是Windows-1252),你会更经常地纠正。你仍然需要通过回退来阅读这样的事情。 decode方法采用名为errors的第二个参数。默认值为'strict',但您也可以'ignore''replace''xmlcharrefreplace'(不合适),'backslashreplace'(不合适),您可以注册拥有codecs.register_error()的后备处理程序。

答案 1 :(得分:8)

许多网页编码错误。要解析HTML,请尝试BeautifulSoup,因为它可以处理在野外找到的许多类型的错误HTML。

  

Beautiful Soup是一个专为快速设计的Python HTML / XML解析器   周转项目,如屏幕抓取。有三个特点   强大:

     
      
  1. 如果给它不好的标记,美丽的汤不会窒息。它会产生一个   解析树,使其与原始图像一样有意义   文献。这通常足以收集您需要的数据   逃跑。

  2.   
  3. Beautiful Soup提供了一些简单的方法和Pythonic   用于导航,搜索和修改解析树的习语:a   用于剖析文档和提取所需内容的工具包。您   不必为每个应用程序创建自定义解析器。

  4.   
  5. 美丽   Soup自动将传入的文档转换为Unicode和传出   文件到UTF-8。 您不必考虑编码,除非   该文档没有指定编码和Beautiful Soup不能   自动检测一个。然后你只需要指定原始编码。

  6.   

强调我的。

答案 2 :(得分:3)

该网站“http://www.homestead.com”并未声称向您发送utf-8,该回复实际上声称是iso-8859-1:

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

您必须对实际收到的页面使用正确的编码,而不是随意猜测。