python BeautifulSoup解决中文乱码问题

刚开始用BeautifulSoup抓取网页,遇到中文乱码问题,在网上搜了一些方法,先记录于此, 看看哪种方法好用

 

1、http://leeon.me/a/beautifulsoup-chinese-page-resolve

import urllib2
from BeautifulSoup import BeautifulSoup

page = urllib2.urlopen('http://www.leeon.me');
soup = BeautifulSoup(page,fromEncoding="gb18030")

print soup.originalEncoding
print soup.prettify()

如果中文页面编码是gb2312,gbk,在BeautifulSoup构造器中传入fromEncoding="gb18030"参数即可解决乱码问题,即使分析的页面是utf8的页面使用gb18030也不会出现乱码问题!

 经测试,该方法可行,但是在python3和BeautifulSoup4.1下要写成   from_encoding="gb18030"

2、http://hi.baidu.com/mengjingchao11/item/604b75e5a426fa2e6cabb856

首先我们要引入urllib2包,使用urllib2中的 urlopen打开指定 的网页。 

page=urllib2.urlopen(网页url)

charset=page.headers['Content-Type'].split(' Charset=')[1].lower()来找到网页的编码格式。

使用BeautifulSoup(page.read(),fromEncoding=charset)使用charset指定的编码格式来读取网页内容。

2、http://hi.baidu.com/dskjfksfj/item/bc658fd1646fef362b35c79b

这两天用python爬取当当网页上面的商品信息,对网页进行解析使用的是beautifulsoup,但是解析的过程中,得到的网页上面的文本信息有些显示出来是正常的,有些则为乱码。

网上找了好久,期间对python的编码方式,以及字符串的各种编码方式之间的转换算是有了初步了解,可惜,试了他们提出来的很多方法,都没有解决问题。最后,仔细琢磨了下文本之间编码转换的原理,用这种方法解决了:

由于当当网页的编码方式是简体中文gb2312 (查看网页源码,可以看到<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />),而python内部的编码方式为unicode,之前的代码是这样的:

contentAll = urllib.urlopen(urlLink).read()
soup = BeautifulSoup.BeautifulSoup(contentAll)  #生成BeautifulSoup对象

经过url定位得到html的document对象之后,此时的编码方式为网页文本的编码方式gb2312,此时送进去BeautifulSoup生成一个BeautifulSoup对象则python以为contentAll为unicode编码,即系统已经以为contentAll为unicode编码了,这将引起后续显示为乱码的问题,因为在网页上面看网页的时候如果改变网页字符编码的时候就会看到乱码。

因此在将contentAll送进去生成BeautifulSoup对象之前必须对其进行解码(decode)为unicode,使用的code为gb2312,修改后的代码如下所示:

contentAll = urllib.urlopen(urlLink).read()
soup = BeautifulSoup.BeautifulSoup(contentAll.decode('gb2312','ignore'))  #生成BeautifulSoup对象

解码的时候加上ignore参数是因为解码过程中有一部分貌似不能正常解码,加上该参数之后能跳过该部分。

后续还需要将得到的信息写进本地文本,由于得到的对象都是unicode编码的,只有将其进行gb2312编码(encode)才能看到有意义的内容,因此在写文件的函数里面将其使用gb2312进行编码再写进文本文件里面去。如下所示:

def writeFile(data, filepath):
    outfile = open(filepath,'ab')
    data = data.encode('gb2312','ignore')
    outfile.write(data)
    outfile.close()

4、http://www.coder4.com/archives/3621

实际上,fromEncoding=”gb18030″并不是一劳永逸的方法,当面对iso-8859-1编码的中文网页时,还是会出现乱码。

BS会乱码的根源是:其内部猜测编码的机制并不完善。

因此,最根本的解决方法是,使用编码自动检测工具,获得网页真实编码,例如chardet这个模块。然后将获取到的encoding设置到BS的fromEncoding构造参数中!!!

 

posted @ 2013-04-08 17:39  todoit  阅读(7845)  评论(0编辑  收藏  举报