Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中从IMAP库读取电子邮件时如何处理所有字符集和内容类型_Python_Python 3.x_Imap_Imaplib_Email Parsing - Fatal编程技术网

在Python中从IMAP库读取电子邮件时如何处理所有字符集和内容类型

在Python中从IMAP库读取电子邮件时如何处理所有字符集和内容类型,python,python-3.x,imap,imaplib,email-parsing,Python,Python 3.x,Imap,Imaplib,Email Parsing,我正在用python阅读来自imap库的电子邮件,该库正在工作,但我正在阅读正文部分并将正文部分存储在数据库中,但有时python代码在解码正文时返回错误,我正在识别正文的内容类型和字符集,但不理解如何处理所有内容类型和字符集,有时它即将出现文本/纯文本,在某些邮件中,utf-8是ascii/ISO-8859/window-1252 请帮助我如何处理所有字符集 找到下面的代码,我目前使用的阅读电子邮件正文只有在需要时,我会提供我的所有代码 预期结果:以UTF-8格式转换/处理电子邮件正文的所有字

我正在用python阅读来自imap库的电子邮件,该库正在工作,但我正在阅读正文部分并将正文部分存储在数据库中,但有时python代码在解码正文时返回错误,我正在识别正文的内容类型和字符集,但不理解如何处理所有内容类型和字符集,有时它即将出现文本/纯文本,在某些邮件中,utf-8是ascii/ISO-8859/window-1252

请帮助我如何处理所有字符集

找到下面的代码,我目前使用的阅读电子邮件正文只有在需要时,我会提供我的所有代码

预期结果:以UTF-8格式转换/处理电子邮件正文的所有字符集,然后以HTML格式显示在门户上。

 if email_message.is_multipart():
    html = None
    multipart = True
    for part in email_message.walk():
        print("%s, %s" % (part.get_content_type(), part.get_content_charset()))
        charset = part.get_content_charset()
        if part.get_content_charset() is None:
            # We cannot know the character set, so return decoded "something"
            text = part.get_payload(decode=True)
            continue
        if part.get_content_type() == 'text/plain' and part.get_content_charset() == 'utf-8':
            # print('text--->1')
            text = str(part.get_payload(decode=True))
            # text = html.decode("utf-8")
            # print(part.get_payload(decode=True))
        if part.get_content_type() == 'text/plain' and part.get_content_charset() != 'utf-8':
            # print('text--->2')
            html = part.get_payload(decode=True)
            # text1 = html.decode("utf-8")
            text1 = html.decode(part.get_content_charset()).encode('utf8')
        if part.get_content_type() == 'text/html' and part.get_content_charset() != 'windows-1252':
            html = part.get_payload(decode=True)
            # text1 = html.decode("utf-8")
            text1 = html.decode(part.get_content_charset()).encode('utf8')
        if part.get_content_type() == 'text/html' and part.get_content_charset() == 'windows-1252':
            html = part.get_payload(decode=True)
            text1 = html.decode("cp1252")
        # if part.get_content_type() == 'text/html' and part.get_content_charset() == 'windows-1252':
        #    html = part.get_payload(decode=True)
        #    text1 = html.decode("latin-1")
        # if text is not None:
        # print(text.strip())
        # prin('Rahul')
        # else:
    # print("text")    #    print( html.strip())
    # print(text1.strip())
    # print("text1")
    # print(text1)
    imageCount = 0
    imageKey = ''
    json_data = {}
    filedata = {}
    mydict1 = ''
    value = ''
    params = ''
    filename = ''
    newFileName = ''
    for part in email_message.walk():
        if part.get_content_maintype() == 'multipart':
            continue
        if part.get('Content-Disposition') is None:
            continue
        if part.get_content_type() == 'message/rfc822':
            part_string = (bytes(str(part), 'utf-8'))
            # part_string = bytes(str(part.get_payload(0)),'utf-8')
            print('EML Part')
            print(part_string)
            filename = part.get_filename()
            # filename = filename.replace('\r', '').replace('\n', '')
            # print(part_string)
            # print(('attachment wala'))
        else:
            part_string = part.get_payload(decode=True)
            # print(part_string)
            # print(('attachment wala'))
            filename = part.get_filename()
            # filename = filename.replace('\r', '').replace('\n', '')
        if filename is not None:
            filepart = []
            try:
                decodefile = email.header.decode_header(filename)
                print('decodefile')
                print(decodefile)
            except HeaderParseError:
                return filename
                #
            for line1, encoding1 in decodefile:
                enc = 'utf-8'
                #        print(encoding)
                if encoding1 is not None:  # else encoding
                    print(type(line1))
                    filepart.append((line1.decode(encoding1)))
                    print('line')
                    print(line1)
                    print(filepart)
                    filename = ''.join(filepart)[:1023]
                else:
                    filename = filename
            dot_position = filename.rfind('.')
            file_prefix = filename[0: dot_position]
            file_suffix = filename[dot_position: len(filename)]
            print(filename)
            print(file_prefix)
            print(file_suffix)
            # filename = filename.decode('utf-8')
            # subject = ''
            file_prefix = file_prefix.replace('/', '_')
            now = datetime.datetime.now()
            timestamp = str(now.strftime("%Y%m%d%H%M%S%f"))
            print('timestamp--->')
            print(timestamp)
            newFileName = file_prefix + "_" + timestamp + file_suffix
            newFileName = newFileName.replace('\r', '').replace('\n', '').replace(',', '')
            filename = filename.replace('\r', '').replace('\n', '').replace(',', '')
            sv_path = os.path.join(svdir, newFileName)
            mydict = filename + '$$' + newFileName
            mydict1 = mydict1 + ',' + mydict
            # print(mydict1)
            value, params = cgi.parse_header(part.get('Content-Disposition'))
            print(value)
            if value == 'inline':
                imageCount = imageCount + 1
                print("newFileName-->" + newFileName)
                filedata[imageCount] = newFileName
                print(filedata)
                json_data = (filedata)
            # inlineImages = inlineImages + ',' + newFileName + '{{' + str(imageCount) + '}}'
            # print(json_data)
            # print('TYPE-->')
            # print(type(raw_email))
            # print(type(part.get_payload(decode=1)))
            # if type(part.get_payload(decode=1)) is None:
            #    print('message Type')
            if not os.path.isfile(sv_path):
                # print('rahul1')
                try:
                    fp = open(sv_path, 'wb')
                    fp.write(part_string)
                    fp.close()
                except TypeError:
                    pass
                    fp.close()

else:
    print("%s, %s" % (email_message.get_content_type(), email_message.get_content_charset()))
    if email_message.get_content_charset() is None:
        # We cannot know the character set, so return decoded "something"
        text = email_message.get_payload(decode=True)
        continue
    if email_message.get_content_type() == 'text/plain' and email_message.get_content_charset() == 'utf-8':
        print('text--->1')
        text = str(email_message.get_payload(decode=True))
        # text = html.decode("utf-8")
        # print(part.get_payload(decode=True))
    if email_message.get_content_type() == 'text/plain' and email_message.get_content_charset() != 'utf-8':
        print('text--->2')
        html = email_message.get_payload(decode=True)
        # text1 = html.decode("utf-8")
        text1 = html.decode(email_message.get_content_charset()).encode('utf8')
    if email_message.get_content_type() == 'text/html' and email_message.get_content_charset() != 'windows-1252':
        html = email_message.get_payload(decode=True)
        # text1 = html.decode("utf-8")
        text1 = html.decode(email_message.get_content_charset()).encode('utf8')
    if email_message.get_content_type() == 'text/html' and email_message.get_content_charset() == 'windows-1252':
        html = email_message.get_payload(decode=True)
        text1 = html.decode("cp1252")
在Python中从IMAP库读取电子邮件时如何处理所有字符集和内容类型

简单回答:
遍历所有消息部分并应用提供的编码设置。我看到您已经这样做了(尽管我会将if-else级联改写成更简单的东西,因为stdlibimpl可以很好地处理它,您的代码目前有点混乱)。这将适用于符合标准的邮件内容。但和往常一样,有许多糟糕的邮件客户端不太关心标准的一致性(从在某些情况下坏掉的好客户端到脚本较弱的垃圾邮件客户端)

长答案:
不可能对所有消息都正确。由于各种原因,解码将失败。每当某一部分解码失败时,问题是——该怎么办?你基本上有以下几种选择:

  • 不要做什么特别的事,只需使用原始内容
    您可以将原始字节内容插入到数据库中,并向用户提供该内容。这对用户来说不是很友好,如果你有一个庞大的用户群,并且有业务限制,那么这也不是你想要的。这仍然是处理破损内容的更简单的方法。如果是2,这也是一种退路。仍然失败

  • 尝试使用一些启发式方法解码内容
    这里开始了令人讨厌的编码——每当一个部分的解码失败时,注释编码和实际内容都有问题。你能在这里做什么?除了检查内容之外,试着找到实际编码的提示(比如UTF8位掩码的模式匹配),甚至蛮力解码。聪明的启发式算法可能希望首先尝试常见的编码错误(例如,测试UTF8或8位编码,如之前的拉丁语-1)。这里不存在一个好的经验法则,因为混乱的文本编码可以从一个错误宣布的编码类型到几个混合的8位编码。虽然第一个问题最有可能被发现,但后一个问题即使通过最先进的启发式算法也永远无法解决,并且应该始终回到1中的解决方案

  • 跳过内容
    不建议使用,因为这可能会对用户隐瞒重要数据。只有在你确信内容是垃圾的情况下才这样做

  • 如果您想采用启发式方法,我建议您执行以下操作:

    • 从标准一致性处理开始,任何遵循标准的消息都应该得到正确处理(在一个完美的世界中,您在这里就完成了)
    • 执行1。作为一般故障切换
    • 从自己的用户处收集典型故障的数据,或在互联网上搜索典型故障(其他邮件客户端已经识别出这些故障并以某种方式处理)
    • 实现2中的启发式,遵循80/20规则(首先实现大多数用户都会受益的东西),其他一切都由1处理
    • 随着时间的推移改进启发式
    • 在任何情况下-尽量避免3

    这是对您的问题的一个非常笼统的回答,如果您有一个特定的问题,也许您应该更详细地解决这个问题。

    为什么缩进这么多?您现在可以检查一下吗?它现在可读吗?是的-看起来好多了。为什么您有大量的编码分支?这样,您的代码几乎无法读取。我建议重新开始清理,只需通过stdlib调用即可处理正确的邮件。我还建议将责任划分为更多的功能…是的,这就是为什么要求处理所有格式的多重编码,如果有一个解决方案可以简单地处理该电子邮件正文的解码,我肯定会将其分离为多个功能现在我关心的是删除多个if/ELSE来处理所有电子邮件正文的解码