Записать html файл из mbox

До того, как группы Yahoo были закрыты, вы могли загружать содержимое группы в файл mbox. Я пытаюсь преобразовать файл mbox в серию html-файлов — по одному для каждого сообщения. Моя проблема связана с кодировкой и специальными символами в html. Вот моя попытка:

import mailbox

the_dir = "/path/to/file"

mbox = mailbox.mbox(the_dir + "12394334.mbox")

html_header = """<!DOCTYPE html>
<html>
<head>
<title>Email message</title>
</head>
<body>"""    
html_footer = '</body></html>'

for message in mbox:
    mess_from = message['from']
    subject = message['subject']
    time_received = message['date']
    if message.is_multipart():
        content = ''.join(str(part.get_payload(decode=True)) for part in message.get_payload())
    else:
        content = message.get_payload(decode=True)
    
    content = str(content)[2:].replace('\\n', '<br/>')
    subject.replace('/', '-')
    fname = subject + " " + time_received + '.html'
        
    with open(the_dir + 'html/' + fname , 'w') as the_file:
        the_file.write(html_header)
        the_file.write('<br/>' + 'From: ' + mess_from)
        the_file.write('<br/>' + 'Subject: ' + subject)
        the_file.write('<br/>' + 'Received: ' + time_received + '<br/><br/>')
        the_file.write(content)

Содержимое сообщения имеет обратную косую черту перед апострофами и другими специальными символами, например:

звездный рейтинг, в настоящее время стоит \xa311,99 [идеальный рождественский подарок]. Реклама окончена - Серьезно, если у вас нет приличной книги о маленькой лодке

Мой вопрос в том, как лучше всего получить содержимое сообщения электронной почты и записать его в html-файл с правильными символами. Я не могу быть первым, кто столкнулся с этой проблемой.


person Dkellygb    schedule 25.01.2021    source источник
comment
Этот ответ может быть полезен.   -  person snakecharmerb    schedule 25.01.2021


Ответы (1)


Я нашел ответ на этот вопрос.

Во-первых, мне нужно было идентифицировать html по подтипу (part.get_content_subtype()). Вот как я знаю, что у меня есть подтип html.

Затем мне нужно было получить набор символов, используя part.get_charsets(). Есть part.get_charset(), но он всегда возвращает None, поэтому я беру первый элемент get_charsets().

Кажется, что get_payload отстает от баса с параметром decode=True, что означает, что он не будет декодировать полезную нагрузку. Затем я декодирую сообщение, используя кодировку, которую получил ранее. В противном случае я декодирую его с помощью decode=False.

Если это текст, я удаляю переводы строки и т. д., добавляю заголовок html, а затем записываю в файл.

Следующие работы,

  • используйте BeautifulSoup, чтобы добавить информацию об отправителе/тему в
  • выяснить, как обрабатывать вложения и связывать с ними html-файлы
  • некоторые символы по-прежнему не отображаются, например £ и т. д.

текст

import mailbox

the_dir = "/path/to/mbox/"

mbox = mailbox.mbox(the_dir + "12394334.mbox")

html_footer = "</body></html>"
html_flag = False

for message in mbox:

mess_from = message['from']
subject = message['subject']
time_received = message['date']
fname = subject + " " + time_received
fname = fname.replace('/', '-')

if message.is_multipart():
    contents_text = []
    contents_html = []
    for part in message.walk():
        maintype = part.get_content_maintype()
        subtype = part.get_content_subtype()
        if maintype == 'multipart' or maintype == 'message':
            # Reject containers
            continue
        if subtype == 'html':
            enc = part.get_charsets()
            if enc[0] is not None:
                contents_html.append(part.get_payload(decode=True).decode(enc[0]))
            else:
                contents_html.append(part.get_payload(decode=False))
        elif subtype == 'text':
            contents_text.append(part.get_payload(decode=False))
        else:       #I will use this to process attachmnents in the future
            continue
        
    if len(contents_html)> 0:
        if len(contents_html)>1:
            print('multiple html')      #This hasn't happened yet
        html_flag = True
        content = '\n\n'.join(contents_html)
          
    else:
        html_flag = False
else:
    content = message.get_payload(decode=False) 
    content = content.replace('\\n', '<br/>')
    content = content.replace('=\n', '<br/>')        
    content = content.replace('\n', '<br/>')
    content = content.replace('=20', '')
    html_header = f""" <!DOCTYPE html>
    <html>
    <head>
    <title>{fname}</title>
    </head>
    <body>"""      
    content = (html_header + '<br/>' + 
               'From: ' + mess_from + '<br/>' 
               + 'Subject: ' + subject + '<br/>' + 
               'Received: ' + time_received + '<br/><br/>' + 
               content + html_footer)


with open(the_dir + "html/" + fname + ".html", "w") as the_file:
    the_file.write(content)

печать('Готово!')

person Dkellygb    schedule 26.01.2021