`

python CGI模块获取中文编码问题解决- 部分方案

阅读更多

今天在尝试Python的CGI模块时遇到中文字符不能正确显示的问题,很郁闷.在网上仔细找了找,终于解决了这个问题,现在将解决方法陈述如下,以防下次失误.

 

页面源代码如下

#-*- coding: utf8 -*-

import cgitb , cgi
cgitb.enable()

form = cgi.FieldStorage()
if (form.has_key("name") and form.has_key("addr")):
    print "<p>name:", form["name"].value

    print "<p>addr:", form["addr"].value

[这里仅仅测试addr参数为中文]接收Ascii字符时运行良好,但是接收中文字符时显示乱码,浏览器切换到GB2312编码时

可以正常显示,但是个人要求它成为UTF-8编码显示

 

改成 print "<p>addr:", form["addr"].value.encode('utf-8')  就报如下错误:

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-1: invalid data

 

在参阅了http://blog.chinaunix.net/u2/68206/showart_668359.html 后终于理解,

Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。编码是 unicode -> str,相反的,解码就
是 str -> unicode。剩下的问题就是确定何时需要进行编码或者解码了.关于文件开头的"编码指示",也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用"编码指示"来修正. 关于 sys.defaultencoding,这个在解码没有明确指明解码方式的时候使用。比如我有如下代码:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
s = '中文'  # 注意这里的 str 是 str 类型的,而不是 unicode
s.encode('gb18030')

这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型的,因此
Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是
ANSCII,如果 s 不是这个类型就会出错。拿上面的情况来说,我的 sys.defaultencoding 是 anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position
0: ordinal not in range(128)
对于这种情况,我们有两种方法来改正错误:
一是明确的指示出 s 的编码方式

#! /usr/bin/env python
# -*- coding: utf-8 -*-

s = '中文'
s.decode('utf-8').encode('gb18030')


二是更改 sys.defaultencoding 为文件的编码方式

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
reload(sys) # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入
sys.setdefaultencoding('utf-8')

str = '中文'
str.encode('gb18030')

   

看完之后,改成这样

print "<p>addr:", form["addr"].value.decode('gb2312').encode('utf-8')
成功通过.

 

我总结一下为什么要这么写的原因:

1. 当取回来的数据与你当前脚本中声明的编码不一致时就要做编码转换

2.在编码转换时首先要将该数据以自身编码的格式换成unicode码,再将这个unicode按utf8编码

3.为什么我的浏览器会传回gb2312的编码数据到服务器,这应该和客户端的系统编码有关系

 

 

这里顺便转载一下,关于Python 操作Mysql的中文问题:

 

Python操作MySQL以及中文乱码的问题

下面几个措施,保证MySQL的输出没有乱麻:
   1 Python文件设置编码 utf-8 (文件前面加上 #encoding=utf-8)
    2 MySQL数据库charset=utf-8
    3 Python连接MySQL是加上参数 charset=utf8
    4 设置Python的默认编码为 utf-8 (sys.setdefaultencoding(utf-8)

#encoding=utf-8
import sys
import MySQLdb

reload(sys)
sys.setdefaultencoding('utf-8')

db=MySQLdb.connect(user='root',charset='utf8')
cur=db.cursor()
cur.execute('use mydb')
cur.execute('select * from mytb limit 100')

f=file("/home/user/work/tem.txt",'w')

for i in cur.fetchall():
    f.write(str(i))
    f.write(" ")

f.close()
cur.close()

 

 

 

 

 

 

 

测试以下连接成功: index.psp?name=iamsese&addr=北京

 

 

 

  • 大小: 2.4 KB
5
1
分享到:
评论
4 楼 pythoner126com 2012-09-12  
写得不错,有点长,国内对这个东西热情不是很高,我最近也有翻译,请多多指导:http://www.yiibai.com/python/python_cgi_programming.html
相互学习,共同进步。
3 楼 vb2005xu 2009-08-12  
pdt输出中文乱码的解决
http://www.julabs.com/blog/soft/eclipse-zh/
2 楼 vb2005xu 2009-07-16  
引用
http://hi.baidu.com/yobin/blog/item/1547fbdc6ef53ba4cc116611.html


写了一个简单的脚本,将我的数据整理到Mysql中去。遇到了乱码问题,改了一下,很快就解决了。连接mysql时要注意注明是utf-8字符集,所有中文都要是utf-8,如果有GBK也要先转换成utf-8,把握这个原则,中文乱码问题是不会有的。

转换脚本如下:


#-*- coding: utf-8 -*-,
#coding = utf-8

import MySQLdb,os

def wgdata2DB():
    print "Convert weg game data to mysql"
    db=MySQLdb.connect(host='localhost',      #连接数据库
                      user='root',
                      passwd='123456',
                      db='testdb',
                      charset="utf8")     #这里要注明是utf8字符集,文件开头最好也加上utf-8的声明

    cursor=db.cursor()
      
    if os.path.exists('test.dat'):
        rFile = open('test.dat', 'r')
        lines = rFile.readlines()
        rFile.close()
        
        loop = 0
        for line in lines:
            print "handle line:%d" % (loop)
            myset = line.split(' ')
            
            sqlstr = "INSERT INTO wg_Content (type,title,url,speed,des,size) VALUES('%s','%s','%s','%s','%s','%s')" \
                %(myset[0],myset[1],myset[2],myset[3],myset[4],myset[5])
            cursor.execute(sqlstr)
            loop += 1            
            db.commit()
    cursor.close()
    db.close()
1 楼 vb2005xu 2009-07-16  
Python操作MySQL需要安装Python-MySQL

1 Python文件设置编码 utf-8 (文件前面加上 #encoding=utf-8)
2 MySQL数据库charset=utf-8
3 Python连接MySQL是加上参数 charset=utf8
4 设置Python的默认编码为 utf-8 (sys.setdefaultencoding(utf-8)
#encoding=utf-8
import sys
import MySQLdb

reload(sys)
sys.setdefaultencoding('utf-8')

db=MySQLdb.connect(user='root',charset='utf8')
cur=db.cursor()
cur.execute('use mydb')
cur.execute('select * from mytb limit 100')

f=file("/home/user/work/tem.txt",'w')

for i in cur.fetchall():
     f.write(str(i))
     f.write(" ")

f.close()
cur.close()



推荐使用SQLObject,我在写测试代码时,在SQLITE中没有出现这个问题,因为turbogears缺省类库都是unicode编码的

相关推荐

    Python 核心编程 第二版

    第1部分占据了大约三分之二的篇幅,阐释这门语言的“核心”内容,包括基本的概念和语句、语法和风格、 Python对象、数字类型、序列类型、映射和集合类型、条件和循环、文件和输入/输出、错误和异常、函数和函数式...

    Python核心编程第二版

    第1部分 Python核心  第1章 欢迎来到Python世界   1.1 什么是Python   1.2 起源   1.3 特点   1.3.1 高级   1.3.2 面向对象   1.3.3 可升级   1.3.4 可扩展   1.3.5 可移植性   1.3.6...

    Python核心编程第二版(ok)

    第1部分 Python核心  第1章 欢迎来到Python世界   1.1 什么是Python   1.2 起源   1.3 特点   1.3.1 高级   1.3.2 面向对象   1.3.3 可升级   1.3.4 可扩展   1.3.5 可移植性   1.3.6...

    python对html代码进行escape编码的方法

    python包含一个cgi模块,该模块有一个escape函数可以用来对html代码进行编码转换 import cgi s1 = "Hello &lt;strong&gt;world&lt;/strong&gt;" s2 = cgi.escape(s1) assert s2 == "Hello &lt;strong&gt;world&lt;/strong&gt;" 希望本文所述...

    Python基础教程(第3版)-201802出版-文字版

    久负盛名的 Python 入门经典针对 Python 3 全新升级十个出色的项目,让你尽快可以使用 Python 解决实际问题目录第 1章 快速上手:基础知识 ........................ 1 1.1 交互式解释器 .............................

    Python Cookbook

    6.5 继承的替代方案-自动托管 231 6.6 在代理中托管特殊方法 234 6.7 有命名子项的元组 237 6.8 避免属性读写的冗余代码 239 6.9 快速复制对象 240 6.10 保留对被绑定方法的引用且支持垃圾回收 243 6.11 缓存...

    Python详细教程.rar

    中文编码 基础语法 变量类型 运算符 条件语句 循环语句 数字 字符串 列表 元组 字典 日期时间 函数 模块 文件 异常 面向对象 正则 CGI mysql数据库 网络编程socket 多线程 xml GUI编程 JSON 例子

    SciTE 1.77 中文版.rar

    它支持代码高亮、自动完成、代码折叠、括号匹配、自定义模块等! 它几乎可以用到目前任何的主流语言上面,而且还支持众多的配置文件的高亮折叠,突出等效果!如 Apache 的 conf 文件 php.ini 文件像平时我们在改这些...

    Tcl_TK编程权威指南pdf

    本书的大部分内容是有关Tcl脚本编程的,而有关使用C语言来创建Tcl扩展模块的内容没有着重讲述。我有幸一直参与Tcl核心技术的开发活动,希望通过本书能够将自己使用Tcl时获得的切身体会表达出来。 为什么要使用Tcl ...

    PHP基础教程 是一个比较有价值的PHP新手教程!

    解决方法就是将经常用来编写CGI程序的语言的解释器编译进你的web服务器(比如mod_perl,JSP)。PHP就可以以这种方式安装,虽然很少有人愿意这样以CGI方式安装它。内嵌的PHP可以具有更高的可伸缩性。 - 更多特点 PHP的...

Global site tag (gtag.js) - Google Analytics