加载带有西里尔符号的网址

时间:2010-05-14 15:19:10

标签: python url urllib

我必须加载一些带有西里尔符号的网址。我的脚本应该使用这个:

http://wincode.org/%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/

如果我在浏览器中使用它,它将替换为普通符号,但是urllib代码失败并出现404错误。如何正确解码这个网址?


当我在代码中直接使用该URL时,例如address ='that address',它完美无缺。但我使用解析页面获取此URL。我有一个内容为西里尔字母的网址列表。也许他们有不正确的编码?这是更多代码:

requestData = urllib2.Request( %SOME_ADDRESS%, None,  {"User-Agent": user_agent})
requestHandler = pageHandler.open(requestData)

pageData = requestHandler.read().decode('utf-8')
soupHandler = BeautifulSoup(pageData)

topicLinks = []
for postBlock in soupHandler.findAll('a', href=re.compile('%SOME_REGEXP%')):
    topicLinks.append(postBlock['href'])

postAddress = choice(topicLinks)

postRequestData = urllib2.Request(postAddress, None,  {"User-Agent": user_agent})
postHandler = pageHandler.open(postRequestData)
postData = postHandler.read()

  File "/usr/lib/python2.6/urllib2.py", line 518, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 404: Not Found

2 个答案:

答案 0 :(得分:4)

  

我有一个内容为西里尔字母的网址列表。

好的,如果它包含原始(不是%编码的)西里尔字符,那就不像示例,实际上它根本就不是URL。

其中包含非ASCII字符的地址称为IRI。 IRI不应该用在HTML链接中,但浏览器倾向于修复这些错误。

要将IRI转换为可以使用urllib打开的URI,您必须:

  1. 使用Punycode(IDNA)对主机名部分中的非ASCII字符进行编码。

  2. 将IRI的其余部分中的非ASCII字符编码为UTF-8字节并对其进行URL编码(在示例URL中生成%D0%BF...)。

  3. an example implementation

答案 1 :(得分:1)

您可以尝试使用urllib.unquote方法。

>>> import urllib
>>> string = urllib.unquote("http://wincode.org/%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5/")
>>> print string.decode("utf-8")
http://wincode.org/программирование/