【已解决】python中文字符乱码(GB2312,GBK,GB18030相关的问题)
http://againinput4.blog.163.com/blog/static/1727994912011111011432810/
【已解决】python中文字符乱码(GB2312,GBK,GB18030相关的问题)
【背景】
在玩wordpress的一个博客搬家工具BlogMover,其包含几个python脚本,其中有个是163博客搬家用的163-blog-mover.py,实现抓取网易博客的日志,然后导出xml。
但是其工具现在(2011-12-10)已经失效了。经过自己一点修改后,可以实现获得文章标题了。
用法还是原先的用法:
163-blog-mover.py -fhttp://againinput4.blog.163.com/blog/static/172799491201111893853485/ |
获得的此篇日志的标题:
【已解决】允许hi-baidu-mover_v2.py出错:UnboundLocalError: local variable 'linkNode' referenced before assignment
中包含中文,在将该标题打印出来到log中后,却发现中文部分显示乱码:
????·??????????íhi-baidu-mover_v2.py???í??UnboundLocalError: local variable 'linkNode' referenced before assignment
所以想要去除乱码,正确显示中文。
【解决过程】
1. 本身那段文字,是从网页中抓取的,关于该日志的中文编码,也已经从网页中的:
<metahttp-equiv="content-type"content="text/html;charset=gbk"/>
看出来是GBK了。
而python中,原先默认编码发现是ascii,后来去通过:
reload(sys)
sys.setdefaultencoding('utf-8')
去将默认编码设置为utf-8,但是结果输出还是乱码。
2.后来网上找了一堆帖子, 包括最后这个:
http://www.tangc.com.cn/view_article_117.html
去尝试先对其解码,再编码:
string.decode('GBK').encode(utf-8')
结果还是乱码:
隆戮虏驴路脰陆芒戮枚隆驴脭脢脨铆hi-baidu-mover_v2.py鲁枚麓铆拢潞UnboundLocalError: local variable 'linkNode' referenced before assignment
而又去试了试其他的,比如:
temp.string.strip().decode('GBK').encode('mcbs)
输出也是乱码,和不转换之前是一样的。
总之,还是无法及解决乱码问题。
3.后来,在学习Beautiful Soup的时候:
http://www.crummy.com/software/BeautifulSoup/documentation.zh.html#contents
Beautiful Soup 会按顺序尝试不同的编码将你的文档转换为Unicode:
|
得知Beautiful Soup默认已经可以通过你所给的链接中的HTML源码中的meta的http-equiv头,去解析charset,已经可以知道网页的编码是上面所显示的GBK了,而且自动会去以该编码获得网页内容,然后自动输出为utf-8的unicode了。
所以python中去:
print "###originalEncoding=",soup.originalEncoding,"declaredHTMLEncoding=",soup.declaredHTMLEncoding,"fromEncoding=",soup.fromEncoding |
就已经可以得到输出:
###originalEncoding= windows-1252 declaredHTMLEncoding= gbkfromEncoding= None |
了,但是也还是很奇怪,为何原先网页的编码,HTML中声明的是GBK,而Beautiful Soup解析出来的网页原始编码originalEncoding是windows-1252呢,两者不一样(我另外试了别的一个百度的网页,declaredHTMLEncoding是GBK,originalEncoding也是declaredHTMLEncoding)。
也因此,自己手动尝试,在open URL的时候,给Beautiful Soup传递GBK参数,即:
page = urllib2.build_opener().open(req).read() soup = BeautifulSoup(page, fromEncoding="GBK") |
结果也还是不行。
关于此问题,后来网上找到了解释:
http://groups.google.com/group/python-cn/browse_thread/thread/cb418ce811563524
请注意 gb2312 不是 “gb2312”,凡 gb2312 的请换成 gb18030.
微软将 gb2312 和 gbk 映射为 gb18030,方便了一些人,也迷惑了一些人。 |
即,实际上该网页是GB18030的编码,所以按照这里:
http://blog.csdn.net/fanfan19881119/article/details/6789366
(原始出处为:http://leeon.me/a/beautifulsoup-chinese-page-resolve)
的方法,传递GB18030给fromEncoding,才可以:
page = urllib2.build_opener().open(req).read() soup = BeautifulSoup(page, fromEncoding="GB18030") |
而其中,也解释了,为何HTML标称的GBK的编码,但是却解析出来为windows-1252了:
最近需要写一个python的RSS抓取解析程序,使用了feed parser。但是对于百度新闻的RSS,其编码方式为gb2312,feed parser探测出来的编码却是windows-1252,结果中文内容都是一堆乱码。
问题在于,并不是feedparser不能识别出gb2312编码,而是国人们往往将gb2312与gbk编码等同,某些已经使用了gbk编码里的字符的,仍然声称内容为gb2312编码。feedparser对gb2312编码严格遵循gb2312字符集范围,当探测到超出这一范围的字符,便将编码回退到windows-1252。由于百度的RSS实际使用的应该是gbk编码,里面含有超出gb2312范围的字符,于是feedparser便擅自决定了将编码退回windows-1252,导致了中文乱码的现象。 |
【总结】
以后用python的Beautiful Soup去解析中文网页的话:
1.如果本身网页的编码自己标称的,和本身其中文字符所用编码完全符合的话,即没有部分字符超出了其所标称的编码,比如标称为GBK,网页所有的内容,都的确是GBK编码,没有超出的其他字符(比如属于GB18030的编码),那么,是可以通过:
page = urllib2.urlopen(url) soup = BeautifulSoup(page) #此处不需要传递参数,BeautifulSoup也完全可以自己去解析网页内容所使用的编码 print soup.originalEncoding |
而得到真实的网页的编码的。
2.讨论中文乱码问题之前,先解释关于中文字符编码:
时间上的发展先后是,GB2312,GBK,GB18030,编码技术上都是兼容的。
从所包含的中文字符个数来说,算是:GB2312 < GBK < GB18030,也因此,才可能会出现上面所说的,标称GB2312的,部分字符用到了GBK里面的,或者是标称GBK的,部分字符用到了GB18030里面的,所以被人家编码工具解析错误,退回认为编码是最基本的windows-2152了。
而我这里的情况就是属于后者,网易博客网页中,自己声称是GBK,但是很多中文字符用的是GB18030。
总的说,现在实际情况是,由于编写网页代码的人所用的字符编码所不同,以及自己在网页中声称的编码和实际自己网页所用的编码不同,导致了中文网页出现乱码。所以,要先搞懂这些中文字符编码之间关系,以及历史上的逻辑前后关系,才可能解决这类问题。
关于中文字符编码,更多详细解释请参考这里:
中文字符编码标准+Unicode+Code Page
http://bbs.chinaunix.net/thread-3610023-1-1.html
所以:
(1)如果是网页标称为GB2312,但是部分字符用到了GBK的了,那么解决办法就是在调用BeautifulSoup,传递参数fromEncoding="GBK",即:
page = urllib2.build_opener().open(req).read() soup = BeautifulSoup(page, fromEncoding="GBK") |
(2)如果是网页标称为GBK,但是部分字符用到了GB18030的了,那么解决办法就是在调用BeautifulSoup,传递参数fromEncoding="GB18030",即:
page = urllib2.build_opener().open(req).read() soup = BeautifulSoup(page, fromEncoding="GB18030") |
(3)实际上由于GB18030从字符数上都涵盖了GB2312和GBK,所以如果是上述两种任意情况,即只要是中文字符出现乱码,不管是标称GB2312中用到了GBK,还是标称GBK中用到了GB18030,那么都直接传递GB18030,也是可以的,即:
soup = BeautifulSoup(page, fromEncoding="GB18030") |
即可。
【已解决】python中文字符乱码(GB2312,GBK,GB18030相关的问题)的更多相关文章
- python中文字符乱码(GB2312,GBK,GB18030相关的问题)
转自博主 crifan http://againinput4.blog.163.com/blog/static/1727994912011111011432810/ 在玩wordpress的一个博客搬 ...
- 字符集、字符编码、国际化、本地化简要总结(UNICODE/UTF/ASCII/GB2312/GBK/GB18030)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明 普通的linux 和 普通的windows. ...
- Python中文字符的理解:str()、repr()、print
Python中文字符的理解:str().repr().print 字数1384 阅读4 评论0 喜欢0 都说Python人不把文字编码这块从头到尾.从古至今全研究通透的话是完全玩不转的.我终于深刻的理 ...
- JAVA的中文字符乱码问题
来源:http://luzefengoo.blog.163.com/blog/static/1403593882012754428536/ JAVA的中文字符乱码问题一直很让人头疼.特别是在WEB应用 ...
- 解决 python 读取文件乱码问题(UnicodeDecodeError)
解决 python 读取文件乱码问题(UnicodeDecodeError) 确定你的文件的编码,下面的代码将以'utf-8'为例,否则会忽略编码错误导致输出乱码 解决方案一 with open(r' ...
- 字符编码-ASCII,GB2312,GBK,GB18030
ASCII ASCII,GB2312,GBK,GB18030依次增加,向下兼容. 手机只需要支持GB2312 电脑中文windows只支持GBK 发展历程 如果你使用编译器是python2.0版本,默 ...
- GB2312,GBK,GB18030,UTF8四种汉字编码标准有什么差别和联系
从GB2312.GBK 到 GB18030,这些编码方法是向下兼容的,即同一个字符在这些方案中总是有同样的编码,后面的标准支持很多其它的字符.在这些编码中,英文和中文能够统一地处理. 区分中文编 ...
- 汉字编码:GB2312, GBK, GB18030, Big5
前一篇博文:ANSI是什么编码?中有这样一段小故事: 话说计算机是由美国佬搞出来的嘛,他们觉得一个字节(可以表示256个编码)表示英语世界里所有的字母.数字和常用特殊符号已经绰绰有余了(其实ASCII ...
- 解决python中文乱码的方法
首先需要说明的是,windows下的文件路径,cmd窗口等默认编码都是gbk 但在windows下编写python程序的时候,我们一般采用的编码是utf-8 二者不一致是导致乱码的根本原因! 在pyc ...
随机推荐
- java基础 4 继承(1)访问权限与作用域
作用域与可见性 当前类 同一package 子类 其他package public √ √ √ √ protected √ √ √ defalut √ √ private √
- flash update
https://get.adobe.com/cn/flashplayer/otherversions/
- day5-WordCount
1. wordcount示例开发 1.1. wordcount程序整体运行流程示意图 map阶段: 将每一行文本数据变成<单词,1>这样的kv数据 reduce阶段:将相同单词的一组k ...
- 使用POI操作Excel时new XSSFWorkbook ()报错java.lang.NoSuchMethodError解决方式
使用最新的POI3.11时,在执行 Workbook workBook = new XSSFWorkbook ();这段代码时出现错误: java.lang.NoSuchMethodError: j ...
- Office EXCEL 表格如何设置某个单元格是选择项,如何设置一级下拉菜单
1 比如我要在C这一列都做成下拉菜单,则我选中这一列的第一个单元格,然后点击数据-有效性,然后把允许改成"序列",在来源中输入每一项(用逗号隔开),比如我一共要做四个下拉菜单选项, ...
- Scrum 常见错误实践 之 过长的站会
站会看起来很简单,在实践过程中,却经常会出现控制不当而导致达不到应用效果的状况.我只是结合自己的一些过往经历作一些浅显的总结. 一个很常见的就是站会拖得太长. 一般来说站会不应该超过15分钟,每个人应 ...
- js将月份转换为英文简写的形式
本文通过代码实例介绍一下如何实现将月份转换为英文简写的形式. 比如将一月份转换为Jan,需要的朋友可以做一下参考. 代码实例如下: [JavaScript] 纯文本查看 复制代码运行代码 1 2 3 ...
- 一颗ARM架构芯片的软硬件构成
硬件和软件是一颗芯片系统互相依存的两大部分.本文总结了一颗芯片的软硬件组成.作为对芯片的入门级概括吧. (一)硬件 主控CPU:运算和控制核心.基带芯片基本构架採用微处理器+数字信号处理器(DSP)的 ...
- 游戏server设计的一些感悟
Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 Date:September 30 ...
- Django项目开发-小技巧
当你开发完一个Django项目之后肯定要吧他丢到服务器让跑起来,但是你在自己的环境下安装了好多的包,是不是在服务器中也要一个个的安装了, pip freeze > read.txt #这条命令会 ...