加载带有西里尔字母的 URL

2 投票
3 回答
5098 浏览
提问于 2025-04-15 22:42

我需要加载一些包含西里尔字母的链接。我的脚本应该能处理这个链接:

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错误。怎么才能正确解码这个链接呢?


当我在代码中直接使用这个链接,比如写成 address = '那个链接',它就能正常工作。但我是在解析网页时获取到这个链接的。我有一个包含西里尔字母的链接列表。也许它们的编码不正确?这里还有更多代码:

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

3 个回答

0

下面这段代码对我有效(是对上面Arseny的代码进行了修改):

import urllib.parse
string='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/'
string = urllib.parse.unquote(string,encoding='utf-8') # http://wincode.org/программирование/
2

你可以试试使用 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/программирование/
5

我有一堆网址,里面包含西里尔字母。

好吧,如果这些网址里面有原始的(不是经过百分号编码的)西里尔字符,那就不太像例子中的那样,实际上它根本不是一个网址。

包含非ASCII字符的地址被称为 国际化资源标识符(IRI)。在HTML链接中不应该使用IRI,但浏览器通常会自动修正这些错误。

要把一个IRI转换成可以用 urllib 打开的URI,你需要:

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

  2. 将IRI其余部分的非ASCII字符编码为UTF-8字节,并进行URL编码(结果会像例子中的 %D0%BF... 这样的形式)。

这是一个示例实现

撰写回答