代码之家  ›  专栏  ›  技术社区  ›  ʞɔıu

获取python getaddresses()来解码编码的单词编码

  •  3
  • ʞɔıu  · 技术社区  · 14 年前
    msg = \
    """To: =?ISO-8859-1?Q?Caren_K=F8lter?= <ck@example.dk>, bob@example.com
    Cc: "James =?ISO-8859-1?Q?K=F8lter?=" <jk@example.dk>
    Subject: hello
    
    message body blah blah blah
    
    """
    
    import email.parser, email.utils
    import itertools
    
    
    parser = email.parser.Parser()
    parsed_message = parser.parsestr(msg)
    
    address_fields = ('to', 'cc')
    addresses = itertools.chain(*(parsed_message.get_all(field) for field in address_fields if parsed_message.has_key(field)))
    address_list = set(email.utils.getaddresses(addresses))
    
    
    print address_list
    

    似乎email.utils.getaddresses()无法自动处理 MIME RFC 2047 在地址字段中。

    我怎样才能得到下面的预期结果?

    实际结果:

    set([('', 'bob@example.com'), ('=?ISO-8859-1?Q?Caren_K=F8lter?=', 'ck@example.dk'), ('James =?ISO-8859-1?Q?K=F8lter?=', 'jk@example.dk')])

    set([('', 'bob@example.com'), (u'Caren_K\xf8lter', 'ck@example.dk'), (u'James \xf8lter', 'jk@example.dk')])

    3 回复  |  直到 14 年前
        1
  •  3
  •   ʞɔıu    14 年前

    你想要的功能是 email.header.decode_header ,它返回 (decoded_string, charset) charset 在把它们交给 email.utils.getaddresses

    你可能认为这很简单:

    def decode_rfc2047_header(h):
        return ' '.join(s.decode(charset or 'ascii')
                       for s, charset in email.header.decode_header(h))
    

    def decode_safely(s, charset='ascii'):
        """Return s decoded according to charset, but do so safely."""
        try:
            return s.decode(charset or 'ascii', 'replace')
        except LookupError: # bogus charset
            return s.decode('ascii', 'replace')
    
    def decode_rfc2047_header(h):
        return ' '.join(decode_safely(s, charset)
                       for s, charset in email.header.decode_header(h))
    
        2
  •  1
  •   bobince    14 年前

    是的,那个 email 包接口在很多时候确实不是很有用。

    在这里,你必须使用 email.header.decode_header

    for name, address in email.utils.getaddresses(addresses):
        name= u' '.join(
            unicode(b, e or 'ascii') for b, e in email.header.decode_header(name)
        )
        ...
    
        3
  •  0
  •   iMom0    12 年前

    谢谢加雷斯。你的回答有助于解决一个问题:

    Input: 'application/octet-stream;\r\n\tname="=?utf-8?B?KFVTTXMpX0FSTE8uanBn?="'
    

    在编码的单词周围没有空格会导致 email.Header.decode_header

    if not ' =?' in h:
        h = h.replace('=?', ' =?').replace('?=', '?= ')
    
    Output: u'application/octet-stream; name="(USMs)_ARLO.jpg"'