代码之家  ›  专栏  ›  技术社区  ›  Peter Farmer

在python中将域名转换为idn

  •  5
  • Peter Farmer  · 技术社区  · 14 年前

    我有一个很长的域名列表,需要在其中生成一些报告。该列表包含一些IDN域,尽管我知道如何在命令行上用python转换它们:

    >>> domain = u"pfarmerü.com"
    >>> domain
    u'pfarmer\xfc.com'
    >>> domain.encode("idna")
    'xn--pfarmer-t2a.com'
    >>> 
    

    我正在努力让它与一个从文本文件读取数据的小脚本一起工作。

    #!/usr/bin/python
    
    import sys
    
    infile = open(sys.argv[1])
    
    for line in infile:
        print line,
        domain = unicode(line.strip())
        print type(domain)
        print "IDN:", domain.encode("idna")
        print
    

    我得到以下输出:

    $ ./idn.py ./test 
    pfarmer.com
    <type 'unicode'>
    IDN: pfarmer.com
    
    pfarmerü.com
    Traceback (most recent call last):
      File "./idn.py", line 9, in <module>
        domain = unicode(line.strip())
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 7: ordinal not in range(128)
    

    我也尝试过:

    #!/usr/bin/python
    
    import sys
    import codecs
    
    infile = codecs.open(sys.argv[1], "r", "utf8")
    
    for line in infile:
        print line,
        domain = line.strip()
        print type(domain)
        print "IDN:", domain.encode("idna")
        print
    

    这给了我:

    $ ./idn.py ./test       
    Traceback (most recent call last):
      File "./idn.py", line 8, in <module>
        for line in infile:
      File "/usr/lib/python2.6/codecs.py", line 679, in next
        return self.reader.next()
      File "/usr/lib/python2.6/codecs.py", line 610, in next
        line = self.readline()
      File "/usr/lib/python2.6/codecs.py", line 525, in readline
        data = self.read(readsize, firstline=True)
      File "/usr/lib/python2.6/codecs.py", line 472, in read
        newchars, decodedbytes = self.decode(data, self.errors)
    UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-5: unsupported Unicode code range
    

    这是我的测试数据文件:

    pfarmer.com
    pfarmerü.com
    

    我很清楚我现在需要了解Unicode。

    谢谢,

    彼得

    2 回复  |  直到 12 年前
        1
  •  14
  •   knitti freethinker    14 年前

    您需要知道您的文件保存在哪个编码中。这可能是类似于“utf-8”(不是unicode)或“iso-8859-1”或“cp1252”之类的。

    然后您可以这样做(假设为“utf-8”):

    
    infile = open(sys.argv[1])
    
    for line in infile:
        print line,
        domain = line.strip().decode('utf-8')
        print type(domain)
        print "IDN:", domain.encode("idna")
        print
    

    使用将编码字符串转换为Unicode decode . 将Unicode转换为字符串 encode . 如果您试图对已经编码的内容进行编码,那么python将首先尝试进行解码,使用默认的编解码器“ascii”,它对非ascii值无效。

        2
  •  2
  •   bobince    14 年前

    你的第一个例子很好,除了:

    domain = unicode(line.strip())
    

    您必须在此处指定特定的编码: unicode(line.strip(), 'utf-8') . 否则,您将得到默认编码,出于安全考虑,它是7位ASCII,因此会出现错误。或者你也可以拼出来 line.strip().decode('utf-8') 就像在Knitti的例子中一样,这两种语法在行为上没有区别。

    然而,从错误无法解码字节0xfc来看,我认为您实际上没有保存 test 作为UTF-8文件。大概这就是第二个例子失败的原因,这个例子在原则上看起来也不错。

    相反,它是ISO-8859-1或非常类似的Windows代码页1252。如果它来自西方Windows设备上的文本编辑器,那么肯定是后者;Linux机器现在默认使用UTF-8。请确保将文件保存为UTF-8,或者使用编码读取文件 'cp1252' 相反。