Сохранение встроенных изображений в электронных письмах с помощью python

#python #image #email

#python #изображение #Адрес электронной почты

Вопрос:

Я пытаюсь захватить изображения во встроенном электронном письме. Проблема в том, что сохраняемое изображение нечитаемо, и я не могу понять, почему. Электронное письмо (сохраняется в виде файла, который я загружаю в начале кода):

 MIME-Version: 1.0

Received: by 10.100.120.7 with HTTP; Tue, 18 Oct 2011 10:36:48 -0700 (PDT)

In-Reply-To: <8B4FDE07A4759840B84FD04B4C88100B010135E81D8C@fxildc03.forexmanage.com>

References: <8B4FDE07A4759840B84FD04B4C88100B010135E81D8C@fxildc03.forexmanage.com>

Date: Tue, 18 Oct 2011 19:36:48  0200

Delivered-To: s.shpiz@gmail.com

Message-ID: <CAEb-As9XVmciajFAwEaFyF8CE4QG0t-Z5zFDDpMWXLqaBur1sA@mail.gmail.com>

Subject: openme

From: Simeon Shpiz <s.shpiz@gmail.com>

To: me <s.shpiz@gmail.com>

Content-Type: multipart/related; boundary=001636c5977303b92404af962ba6



--001636c5977303b92404af962ba6

Content-Type: multipart/alternative; boundary=001636c5977303b91d04af962ba5



--001636c5977303b91d04af962ba5

Content-Type: text/plain; charset=ISO-8859-1



****



--001636c5977303b91d04af962ba5

Content-Type: text/html; charset=ISO-8859-1

Content-Transfer-Encoding: quoted-printable



<div dir=3D"ltr"><div class=3D"gmail_quote"><div lang=3D"EN-US" link=3D"blu=

e" vlink=3D"purple"><div><p class=3D"MsoNormal"><span style=3D"font-size:11=

.0pt;color:#1F497D"><img width=3D"15" height=3D"13" src=3D"cid:image003.png=

@01CC8DCD.30A2A7C0"></span><span style=3D"font-size:11.0pt;color:#1F497D"><=

u></u><u></u></span></p>



</div>

</div></div><br></div>



--001636c5977303b91d04af962ba5--

--001636c5977303b92404af962ba6

Content-Type: image/png; name="image003.png"

Content-Transfer-Encoding: base64

Content-ID: <image003.png@01CC8DCD.30A2A7C0>

X-Attachment-Id: 3e79c375acccec3d_0.1



iVBORw0KGgoAAAANSUhEUgAAAA4AAAANCAIAAAAWvsgoAAAAAXNSR0IArs4c6QAAAAlwSFlzAAAO

yAAADsMBrahYpwAAAItJREFUKFNj/P//PwNxgIk4ZWBVQFOBoBsMsGqrqqr6CgYsaNIPHz6EiMjJ

yb19 xbISE9PLy4uBjLQlSLrFBYWBnITExN9fHyADMJulZCQgOgnrFRUVJRYpXAnETb19evXxJr6

4sULiFJ8IfDt2zegii1btmRkZGBRKi8vjxbSwKjJysoCCjISnwYATtwwhahioZoAAAAASUVORK5C

YII=

--001636c5977303b92404af962ba6--
  

Код python, который я использую:

 import email
from BeautifulSoup  import BeautifulSoup 

message = email.message_from_file(open(r'C:shpiztestmsg12248'))
cid_list = []
images = []
for part in message.walk():
    if str(part.get_content_type()) == 'text/html':
        soup = BeautifulSoup(part.get_payload(decode=True))
        cid = '<%s>'%soup('img')[0]['src'][4:]
        cid_list.append(cid)

for part in message.walk():
    if part.get('Content-ID') in cid_list :
        images.append((part.get_filename(),part.get_payload(decode=True)))
for name, image in images:
    with open(r'c:shpiztest%s'%name,'w') as f:
        f.write(image)
  

К сожалению, сохраненное изображение не очень хорошее. (Ни одна программа не открывает его).

Я просмотрел исходные и новые файлы изображений с помощью notepad , и есть разница — похоже, что разрыв строки, который моя сгенерированная копия не присутствует в оригинале. это не единственное отличие, поскольку удаление строки в notepad не сделало изображение доступным для открытия. Разницу, которую я описал, можно увидеть здесь

Был бы признателен за любую помощь в поиске проблемы.

Ответ №1:

Вы пишете изображение в текстовом режиме, а Python искажает окончания строк. Откройте его в wb режиме mode, чтобы записать его дословно.

Комментарии:

1. Спасибо. Это была проблема.

Ответ №2:

Проблема в этих строках:

 for name, image in images:
    with open(r'c:shpiztest%s'%name,'w') as f:
        f.write(image)
  

Файл, который вы создаете с помощью open, по умолчанию является текстовым файлом. Вы должны использовать ‘b’ вместе с ‘w’. Но я не знаю, решит ли это всю проблему. Возможно, вам также понадобится специализированное средство чтения / записи для графических файлов.

Комментарии:

1. на самом деле единственной проблемой было сохранение с помощью ‘wb’ вместо ‘w ‘. чувствую себя настолько глупо, что потратил много времени, чтобы выяснить это