在url中使用中文其实是一个坏习惯,会带来一系列的转码问题, 我更喜欢英文译名或者id来标识某个uri。但是现实往往是残酷的, 特别是在我们调用别人服务时候,有时候被逼无奈使用中文URL。

Python中unicode转码一向是让人头疼的问题。数次碰壁之后,我也摸出了一些门道, 研读完Python字符串的encode与decode 之后,就自认为找到了万金油,谁知道这次又碰上这个老冤家。

01 Traceback (most recent call last):
02   File "<stdin>", line 1, in <module>
03   File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen
04     return _opener.open(url, data, timeout)
05   File "/usr/lib/python2.6/urllib2.py", line 391, in open
06     response = self._open(req, data)
07   File "/usr/lib/python2.6/urllib2.py", line 409, in _open
08     '_open', req)
09   File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
10     result = func(*args)
11   File "/usr/lib/python2.6/urllib2.py", line 1170, in http_open
12     return self.do_open(httplib.HTTPConnection, req)
13   File "/usr/lib/python2.6/urllib2.py", line 1142, in do_open
14     h.request(req.get_method(), req.get_selector(), req.data, headers)
15   File "/usr/lib/python2.6/httplib.py", line 914, in request
16     self._send_request(method, url, body, headers)
17   File "/usr/lib/python2.6/httplib.py", line 951, in _send_request
18     self.endheaders()
19   File "/usr/lib/python2.6/httplib.py", line 908, in endheaders
20     self._send_output()
21   File "/usr/lib/python2.6/httplib.py", line 780, in _send_output
22     self.send(msg)
23   File "/usr/lib/python2.6/httplib.py", line 759, in send
24     self.sock.sendall(str)
25   File "<string>", line 1, in sendall
26 UnicodeEncodeError: 'ascii' codec can't encode characters in position 7-8: ordinal not in range(128)

这次错误引发是在 urlopen() 引起的,很有特色,开始使用 url.encode('utf-8') 就可以解决了。 今天我做了一些测试。

1. ascii + unicode 测试

01 >>> 'a' + u'b'
02 >>> '你' + u'好'
03 Traceback (most recent call last):
04   File "<stdin>", line 1, in <module>
05 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)
06 >>> u'你' + u'好'
07 u'\u4f60\u597d'
08 >>> u'a' + '你' + u'好'
09 Traceback (most recent call last):
10   File "<stdin>", line 1, in <module>
11 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

上面的测试说明ascii码和unicode码相连操作,结论是有中文记得带上u,就不会有问题。 Python默认解码器是ascii,无法解码unicode中的中文。

2. urllib2的测试

01 >>> import urllib2
02 >>> h1 = 'http://baidu.com'
03 >>> urllib2.urlopen(h1)
04 <addinfourl at 153439532 whose fp = <socket._fileobject object at 0xb74e51ac>>
05 >>> h2 = u'http://baidu.com'
06 >>> urllib2.urlopen(h2)
07 <addinfourl at 153440236 whose fp = <socket._fileobject object at 0x925912c>>
08 >>> h3 = 'http://baidu.com?w=测试'
09 >>> urllib2.urlopen(h3)
10 <addinfourl at 153482348 whose fp = <socket._fileobject object at 0x92593ac>>
11 >>> h4 = u'http://baidu.com?w=测试'
12 >>> urllib2.urlopen(h4)
13 Traceback (most recent call last):
14   File "<stdin>", line 1, in <module>
15   File "/usr/lib/python2.6/urllib2.py", line 126, in urlopen
16     return _opener.open(url, data, timeout)
17   File "/usr/lib/python2.6/urllib2.py", line 391, in open
18     response = self._open(req, data)
19   File "/usr/lib/python2.6/urllib2.py", line 409, in _open
20     '_open', req)
21   File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
22     result = func(*args)
23   File "/usr/lib/python2.6/urllib2.py", line 1170, in http_open
24     return self.do_open(httplib.HTTPConnection, req)
25   File "/usr/lib/python2.6/urllib2.py", line 1142, in do_open
26     h.request(req.get_method(), req.get_selector(), req.data, headers)
27   File "/usr/lib/python2.6/httplib.py", line 914, in request
28     self._send_request(method, url, body, headers)
29   File "/usr/lib/python2.6/httplib.py", line 951, in _send_request
30     self.endheaders()
31   File "/usr/lib/python2.6/httplib.py", line 908, in endheaders
32     self._send_output()
33   File "/usr/lib/python2.6/httplib.py", line 780, in _send_output
34     self.send(msg)
35   File "/usr/lib/python2.6/httplib.py", line 759, in send
36     self.sock.sendall(str)
37   File "<string>", line 1, in sendall
38 UnicodeEncodeError: 'ascii' codec can't encode characters in position 7-8: ordinal not in range(128)

这个测试说明, urllib2.urlopen() 可以接受ascii/unicode的英文,也可以接受ascii的中文, 但是一旦是unicode的中文url,就会报转码错误。

so,请尽量英文url,非要用中文,请记得转码。

【Python开发】Url中文字符时记得转码edcode("utf-8")的更多相关文章

  1. Tomcat 中get请求中含有中文字符时乱码的处理

    Tomcat 中get请求中含有中文字符时乱码的处理

  2. url中传递中文参数时的转码与解码

    URL传递中文参数时的几种处理方式,总结如下: 1.将字符串转码:newString(“xxxxx”.getBytes("iso-8859-1"),"utf-8" ...

  3. Java中读取txt文件中中文字符时,出现乱码的解决办法

    这是我写的一个Java课程作业时,遇到的问题. 问题描述: 我要实现的就是将txt文件中的内容按一定格式读取出来后,存放在相应的数组. 我刚开始运行时发现,英文可以实现,但是中文字符就是各种乱码. 最 ...

  4. python匹配某个中文字符

    python2.7对中文的支持不好是众所周知的,现在遇到这样一个需求,要匹配某个中文字符.查了一个资料,思路就是转化为unicode进行比较,记录如下: line = '参考答案: A' # gbk ...

  5. 【python】-- 字符串、字符编码与转码

    字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 创建字符串很简单,只要为变量分配一个值即可:访问子字符串,可以使用方括号来截取字符串: var1 ...

  6. Python开发技术详解(视频+源码+文档)

    Python, 是一种面向对象.直译式计算机程序设计语言.Python语法简捷而清晰,具有丰富和强大的类库.它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结 ...

  7. ctrl c 中文字符到 vnc 里,中文字符已经被转码

    为了测试程序对多语言字符的支持情况,我找来一段中文和北欧的文字,希望把这些文字上传到elasticsearch,并能正确显示. 首先测试了北欧文字,一切OK. 但是中文复制到 VNC 客户端(Linu ...

  8. 小白的Python之路 day2 字符编码和转码

    字符编码和转码 详细文章: http://www.cnblogs.com/yuanchenqi/articles/5956943.html http://www.diveintopython3.net ...

  9. python开发基础之字符编码、文件处理和函数基础

    字符编码 为什么要有字符编码? 字符编码是为了让计算机能识别我们人写的字符,因为计算机只认识高低电平,也就是二进制数"0","1". 一个文件用什么编码方式存储 ...

随机推荐

  1. 题解 【NOI2010】超级钢琴

    [NOI2010]超级钢琴 Description 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号 ...

  2. maven项目创7 配置分页插件

    页面编写顺序   首先确定是否拥有想要的pojo(对象实体类)———>dao层mybatis配置——>service层的接口及实现类——>controller(web下) 分页插件作 ...

  3. 51 Nod 1282 时钟 (循环中的最小表示+哈希)

    1282 时钟  题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 有N个时钟,每个时钟有M个指针,P个刻度.时钟是圆形 ...

  4. TTTTTTTTTTTTTTTT #7 div1 A Breadth-First Search by Foxpower 在线LCA(倍增),模拟

    A - Breadth-First Search by Foxpower Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format ...

  5. easyUI datagrid中checkbox选中事件以及行点击事件,翻页之后还可以选中

    DataGrid其中与选择,勾选相关 DataGrid属性:singleSelect boolean 如果为true,则只允许选择一行. false ctrlSelect boolean 在启用多行选 ...

  6. Spring Boot教程(三十三)使用Redis数据库(1)

    Spring Boot中除了对常用的关系型数据库提供了优秀的自动化支持之外,对于很多NoSQL数据库一样提供了自动化配置的支持,包括:Redis, MongoDB, Elasticsearch, So ...

  7. SQL语句中 NOT IN 子句的“正确打开方式”

    在写SQL语句的时候,若where条件是判断用户不在某个集合当中,我们习惯使用 where 列名 not in (集合) 子句,这种写法本身没有问题,但实践过程中却发现很多人在写类似的SQL语句时,写 ...

  8. 记一次newApiHadoopRdd查询数据不一致问题

    现象: +----------+-------+--------+-----+-----+-----+----+----+------+---------+-------+--------+----- ...

  9. Vue_(组件)计算属性

    Vue计算属性中文文档 传送门 Vue计算属性:更强大的属性声明方式,可以对定义的属性进行逻辑处理与数据监视; 注意:模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的.在模板中放入太多的逻辑 ...

  10. Chrome 神器,神奇的技巧

    谷歌开发者工具是前端日常不可缺少的神奇,写布局,找 bug,优化加载速度统统靠他.但是你真的了解他么?这篇文章是专门介绍谷歌浏览器各种好用小技巧的.不是什么长篇大论,旨在提高你的开发效率,早日完工回家 ...