我遇到了一个奇怪的情况:
我正在卷曲这样的网址:def check_urlstatus(url):
h = httplib2.Http()
try:
resp = h.request("http://" + url, 'HEAD')
if int(resp[0]['status']) < 400:
return 'ok'
else:
return 'bad'
except httplib2.ServerNotFoundError:
return 'bad'
如果我尝试用以下方法测试:
if check_urlstatus('.f.de') == "bad": #<--- error happening here
#..
#..
它说:
UnicodeError: label empty or too long
我在这里造成的问题是什么?
编辑:这是使用idna的追溯。我想,它试图将输入分割为.
,在这种情况下,第一个标签为空,这是第一个.
之前的速度。
答案 0 :(得分:15)
问题是您的网址无法按照IDNA
rules正确编码,这会管理国际化域名的转换方式:
域名的ASCII和非ASCII格式之间的转换是 通过称为ToASCII和ToUnicode的算法完成。这些 算法不是作为一个整体应用于域名,而是 个人标签。例如,如果域名是 www.example.com,然后标签是www,example和com。 ToASCII或 ToUnicode 分别应用于这三个。
这两种算法的细节很复杂,并在中指定 RFC 3490.以下概述了它们的功能。
ToASCII保留任何ASCII标签,但如果标签将失败 不适用于域名系统。如果给出包含的标签 至少有一个非ASCII字符,ToASCII将应用Nameprep 算法,将标签转换为小写并执行其他操作 规范化,然后将结果转换为ASCII使用 Punycode [16]之前加上四个字符的字符串&#34; xn - &#34;。[17] 这个四字符串称为ASCII兼容编码 (ACE)前缀,用于区分Punycode编码标签 普通的ASCII标签。 ToASCII算法可能会以多种方式失败; 例如,最终字符串可能超过a的63个字符的限制 DNS名称。 ToASCII失败的标签不能用于 国际化域名。
在您的情况下,&#39;&#39; (空白)不是有效的域名字符,您最终会得到:
>>> '.f.de'.encode('idna')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/encodings/idna.py", line 164, in encode
result.append(ToASCII(label))
File "/usr/lib/python2.6/encodings/idna.py", line 73, in ToASCII
raise UnicodeError("label empty or too long")
UnicodeError: label empty or too long
如果您将域名更改为&#39; a.f.de&#39;它不应该引起这种例外。