首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何用urlopen获取非ascii url?

如何用urlopen获取非ascii url?
EN

Stack Overflow用户
提问于 2010-12-08 16:06:33
回答 10查看 34.6K关注 0票数 51

我需要从具有非ascii字符的URL中获取数据,但是urllib2.urlopen拒绝打开资源并引发:

代码语言:javascript
运行
复制
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0131' in position 26: ordinal not in range(128)

我知道URL不符合标准,但我没有机会更改它。

使用Python访问包含非ascii字符的URL所指向的资源的方法是什么?

编辑:,换句话说,可以/如何打开URL,例如:

代码语言:javascript
运行
复制
http://example.org/Ñöñ-ÅŞÇİİ/
EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2010-12-08 19:13:27

严格地说,URI不能包含非ASCII字符;您拥有的是一个IRI

若要将IRI转换为普通的ASCII URI,请执行以下操作:

  • 地址主机名部分中的非ASCII字符必须使用旁遮普码-based IDNA算法进行编码;
  • 路径中的非ASCII字符以及地址的大部分其他部分必须按照Ignacio的答案使用UTF-8和%-编码进行编码。

所以:

代码语言:javascript
运行
复制
import re, urlparse

def urlEncodeNonAscii(b):
    return re.sub('[\x80-\xFF]', lambda c: '%%%02x' % ord(c.group(0)), b)

def iriToUri(iri):
    parts= urlparse.urlparse(iri)
    return urlparse.urlunparse(
        part.encode('idna') if parti==1 else urlEncodeNonAscii(part.encode('utf-8'))
        for parti, part in enumerate(parts)
    )

>>> iriToUri(u'http://www.a\u0131b.com/a\u0131b')
'http://www.xn--ab-hpa.com/a%c4%b1b'

(从技术上讲,这在一般情况下仍然不够好,因为urlparse不会分割主机名上的任何user:pass@前缀或:port后缀。只有主机名部分应该被编码。在构建URL时使用普通的urllib.quote.encode('idna')进行编码比将IRI分开要容易得多。)

票数 57
EN

Stack Overflow用户

发布于 2015-03-24 11:32:16

在python3中,对非ascii字符串使用urllib.parse.quote函数:

代码语言:javascript
运行
复制
>>> from urllib.request import urlopen                                                                                                                                                            
>>> from urllib.parse import quote                                                                                                                                                                
>>> chinese_wikipedia = 'http://zh.wikipedia.org/wiki/Wikipedia:' + quote('首页')
>>> urlopen(chinese_wikipedia)
票数 44
EN

Stack Overflow用户

发布于 2013-08-16 08:56:41

Python 3有处理这种情况的库。使用urllib.parse.urlsplit将URL拆分为其组件,使用urllib.parse.quote正确引用/转义unicode字符,并使用urllib.parse.urlunsplit将其重新连接起来。

代码语言:javascript
运行
复制
>>> import urllib.parse
>>> url = 'http://example.com/unicodè'
>>> url = urllib.parse.urlsplit(url)
>>> url = list(url)
>>> url[2] = urllib.parse.quote(url[2])
>>> url = urllib.parse.urlunsplit(url)
>>> print(url)
http://example.com/unicod%C3%A8
票数 24
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4389572

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档