当url包含非英语语言时如何使用pycurl?

时间:2012-10-04 06:36:38

标签: python pycurl

这是pycurl的sourceforge页面上的示例。如果网址包含中文。我们应该做什么过程?由于pycurl不支持unicode?

import pycurl
c = pycurl.Curl()
c.setopt(pycurl.URL, "http://www.python.org/")
c.setopt(pycurl.HTTPHEADER, ["Accept:"])

import StringIO
b = StringIO.StringIO()
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.MAXREDIRS, 5)
c.perform()
print b.getvalue()

3 个答案:

答案 0 :(得分:1)

这是一个演示三个不同问题的脚本:

  • Python源代码中的非ascii字符
  • 网址中的非ascii字符
  • html内容中的非ascii字符
# -*- coding: utf-8 -*-
import urllib
from StringIO import StringIO
import pycurl

title = u"UNIX时间" # 1
url = "https://zh.wikipedia.org/wiki/" + urllib.quote(title.encode('utf-8')) # 2

c = pycurl.Curl()
c.setopt(pycurl.URL, url)
c.setopt(pycurl.HTTPHEADER, ["Accept:"])

b = StringIO()
c.setopt(pycurl.WRITEFUNCTION, b.write)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.MAXREDIRS, 5)
c.perform()

data = b.getvalue() # bytes
print len(data), repr(data[:200])

html_page_charset = "utf-8" # 3
html_text = data.decode(html_page_charset)
print html_text[:200] # 4

注意:代码中的所有utf-8都是完全独立的。

  1. Unicode文字使用您在其中定义的任何字符编码 文件顶部。确保您的文本编辑器尊重该设置

  2. 网址中的路径应使用utf-8进行编码 百分比编码(urlencoded)

  3. 有几种方法可以找到html页面字符集。看到 Character encodings in HTML。 @ Oz123提到的某些库如requests会自动执行:

    # -*- coding: utf-8 -*-
    import requests
    
    r = requests.get(u"https://zh.wikipedia.org/wiki/UNIX时间")
    print len(r.content), repr(r.content[:200]) # bytes
    print r.encoding
    print r.text[:200] # Unicode
    
  4. To print Unicode to console您可以使用PYTHONIOENCODING environment variable设置终端理解的字符编码

  5. 另请参阅The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)和特定于Python的Pragmatic Unicode

答案 1 :(得分:0)

尝试urllib.quote,它将用转义序列替换非ASCII字符:

import urllib

url_to_fetch = urllib.quote(unicode_url)

编辑:只引用路径,你必须用urlparse拆分完整的URL,引用路径,然后使用urlunparse获取要获取的最终URL。

答案 2 :(得分:0)

只需将您的网址编码为“ utf-8”,一切都会好起来的。来自文档:

  

在Python 3下,字节类型保存任意编码的字节字符串。 PycURL将接受libcurl指定“字符串”参数的所有选项的字节值:

>>> import pycurl
>>> c = pycurl.Curl()
>>> c.setopt(c.USERAGENT, b'Foo\xa9')
# ok
  

str类型保存Unicode数据。 PycURL将仅接受包含ASCII码点的str值:

>>> c.setopt(c.USERAGENT, 'Foo')
# ok

>>> c.setopt(c.USERAGENT, 'Foo\xa9')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xa9' in position 3: 
ordinal not in range(128)

>>> c.setopt(c.USERAGENT, 'Foo\xa9'.encode('iso-8859-1'))
# ok

[1] boost asio