繁体   English   中英

如何使用 Python 在现有 eml 文件中添加 pdf 附件?

[英]How to add pdf attachment in an existing eml file using Python?

目前我正在处理 eml 文件,并且我正在处理这些文件:

我必须更改发件人名称并将相同的 eml 文件发送给那些发件人,但我想将.eml 文件添加到我现有的

我已经使用替换 header 命令使用 email.parser 库成功更改了更改的发件人。

例如:

from email.parser import Parser
f = open('C:\\Users\\Downloads\\Message.eml', 'r+')
header = Parser().parse(f)

headers.replace_header(headername, headervalue)
headers.replace_header('to', 'name@gmail.com') 

但现在我被困在如何在相同.eml 文件的 email 正文中添加 pdf 附件。 下面是一个 .eml 文件的示例。 在此我想添加一个附件。

你们能帮忙吗?

.eml 文件模板:

Delivered-To: ***@gmail.com
Received: by 2002:ac9:1e03:0:0:0:0:0 with SMTP id r3csp1380999oci;
        Thu, 6 May 2021 03:24:14 -0700 (PDT)
X-Google-Smtp-Source: ABdhPJxznI2eQK4UcAUk1vJbeKdYMovRwYMwxz4trgXWy7O+V1jklccpi92jvFWplswmqnBJfdpV
X-Received: by 2002:a17:2:94:b9:ec:7fd5:193e with SMTP id w4-20020a1709029a84b02900ec7fd5193emr3638953plp.62.1620296654743;
        Thu, 06 May 2021 03:24:14 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1620296654; cv=none;
        d=google.com; s=arc-20160816;
        b=EH7EGZH8A3o9/LvvqIgO3KaZPU82Jn0iX0/kGV5W/tawujBF7y3qV3Er4lpFtX
         rm1jiy+cH3CPEHEiAyyd3XSuBZFA+AoE8xpoZxXaTxmqB6vBQXVWigVUUTKcsl71CSVs
         xLG7NHWsFABWEdemJY/cnibY85tpk1NpVISzDihAd4IShMKOGlYqoOlyWf06pdyIc2y6
         DZVYrlo/oWsnD2VT5nYiVqMeOwjUKIVg9ACyZIIRpmMQT/2/lutcsrLPMBBJbLK1vpgU
         jpZHu3s++EFPjmuTijNbyvv/5d5RrcsOwvLpWqk
         8U1A==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=from:subject:sender:message-id:to:mime-version:date:dkim-signature;
        bh=oz3nVaiXvPhENQytolVf3ACAgfI2p8aslAq1BN/w55M=;
        b=fUeNvuOk3JjseXNpa+wFWtdmRjgG/Le5G62cV0ZMbelccGKi1H7GWx
         Exred4q9phvSSGV7ZuE+U5MXpwL1tXmPYZhHO+fj5uPEt6dY2x
         Yqg2/1IxDhcd/3NLH8CB19AolyRgAA8Qn+ThyBgpHs8mCVQ0f5XzxZvP/rKf
         WXxyQwA/1CcOPEcDlaOPAZNngacjvxeecjWWLrHUK1eH
         bETcDxabCPKXagRnP4xDXwTSqzj4Gtjsbc7 +v
         WGfw==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@mail.com header.s=mail header.b=LRDuMb9q;
       spf=pass (google.com: domain of ***@mail.com designates ****.137.**.*** as permitted sender) smtp.mailfrom=***@mail.com;
       dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=mail.com
Return-Path: <***@mail.com>
Received: from mail.com (f4mail-235-203. mail.com. [***.137.**.***])
        by mx.google.com with ESMTPS id l10si2328115pgb.331.2021.05.06.03.24.13
        for <xxxxx@gmail.com>
        (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
        Thu, 06 May 2021 03:24:14 -0700 (PDT)
Received-SPF: pass (google.com: domain of ***@mail.com designates ***.137.**.*** as permitted sender) client-ip=***.137.**.***;
Authentication-Results: mx.google.com;
       dkim=pass header.i=@mail.com header.s=mail header.b=LRDuMb9q;
       spf=pass (google.com: domain of ***@mail.com designates ***.137.**.*** as permitted sender) smtp.mailfrom=***@mail.com;
       dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=mail.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mail.com;
    s=mail; t=1620296652;
    bh=oz3nVaiXvPhENQytolVf3ACAgfI2p8aslAq1BN/w55M=;
    h=MIME-Version:From:Date:Message-ID:Subject:To:Content-Type;
    b=LRDuMb9qOWYq/u397M6T9zLkk1kInTolxD538xl5crHBsb3PL8eR5GiE0Deg7fTNe
     T8+whLVLTServKQLpxrEE3ob/6c5gr11SFYP8dIyzYU+qhbtxp6OJcAnBuxkJSRgRD
     JFQ/6oaHO49Jhz/2qkQ82USjrCi1fiAZe/mBKUGY=
Received: (qmail 20965 invoked by uid 510); 6 May 2021 10:24:12 -0000
x-m-msg: asd54ad564ad7aa6sd5as6d5; a6da7d6asas6dasd77; 5dad65ad5sd;
X-OUT-VDRT-SpamState: 0\LEGIT
X-OUT-VDRT-SpamScore: 0
X-OUT-VDRT-SpamCause: gggruggvucftvghtrhhoucdtuddrgeduledrvdegtddgvdejucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecufdftgfffkffhhfdpqfgfvfdfnecuuegrihhlohhuthemuceftddtnecunecujfgurhepffggvffkshfuhfgtsegrtderredttdejnecuhfhrohhmpedfrfhrihihrghnkhgrucffvghsrghifdcuoehpihihrgguvghsrghiudduuddusehrvgguihhffhhmrghilhdrtghomheqnecuggftrfgrthhtvghrnheptdefkeehkeduhfeljeelleehgefgffeutdeljedtiedtgeeigfdtjeettedvkedtnecukfhppedurddukeeirdduvdegrdduheeinecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmohguvgepshhmthhpohhuth
X-Remote-IP: ***.137.**.***
X-REDF-OSEN: ***@mail.com
Date: 6 May 2021 10:24:12 -0000
MIME-Version: 1.0
To: "***" <***@gmail.com>
Received: from unknown ***.137.**.*** by mail.com via HTTP; 06 May 2021 10:24:12 -0000
X-Senderscore: D=0&S=0
Message-ID: <1620296512.S.1386.3658.f4mail-***-13*.mail.com.1620296652.20941@webmail.mail.com>
Sender: ***@mail.com
Subject: =?utf-8?B?UmVxdWVzdGVkIGRvY3VtZW50cw==?=
From: "Fisrtname Lastname" <***@mail.com>
Content-Type: multipart/alternative;
    boundary="=_f619e79a5c2c1319e417d1bc96f343f8"

--=_f619e79a5c2c1319e417d1bc96f343f8
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="UTF-8"



Hey Name,

I hope you are fine and staying safe.
&nbsp;Please find the attached document of some details for the whole process for this program.&nbsp; Once you go through it if you find interest to know then let&#39;s have a discussion.

Regards,
Name LastName
&nbsp;
--=_f619e79a5c2c1319e417d1bc96f343f8
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"

<br /><br />Hey Name,<br /><br />I hope you are fine and staying safe.<br /=
>&nbsp;<div>Please find the attached document of some details for the whole=
 process for this program.&nbsp; Once you go through it if you find interes=
t to know then let&#39;s have a discussion.<br /><br />Regards,<br />Name L=
astName<br />&nbsp;</div><br>
--=_f619e79a5c2c1319e417d1bc96f343f8--

您使用的是旧版email.message.Message API,它不容易让您在解析的消息中添加附件。 但是切换到现代 Python 3.6+ API 是一个简单且整体的好主意,这让这变得轻而易举。

有点模糊,使email.parser模块生成现代EmailMessage object 而不是传统Message的方法是传入一个policy参数。

顺便说一句,如果 email 消息不是磁盘上的纯 UTF-8,您应该将文件读取为bytes并使用BytesParser以避免出现奇怪的编码错误。 许多现实世界的消息包含 Latin-1 或各种亚洲字符集; 但正确的解决方案是甚至不要尝试猜测 - 只需将其作为二进制 blob 读入,然后让email解析器计算出来。

from email.parser import BytesParser
from email.policy import default

headername = 'sender'
headervalue = 'you need to show us your variables <failure@example.net>'

with open(r'C:\Users\Sun\Download\Message.eml', 'rb') as mess:
    message = BytesParser(policy=default).parse(mess)

message.replace_header(headername, headervalue)
message.replace_header('to', 'name@gmail.com')

message.add_attachment(b'\x00\x00\x00', 'attachment', 'pdf', filename='poop.pdf')

add_attachment方法的文档也有些差。 它的 arguments 是附件正文数据、主要类型和子类型(尽管您可以添加其他参数,如处置,为收件人提供文件名)。 参见例如向 EmailMessage 添加附件引发 TypeError: set_text_content() got an unexpected keyword argument 'maintype'

通常,您可能还想从文件中读取 PDF :

from pathlib import Path

pdf_file = Path(r'C:\windows\horrible\atrocious\nasty\file.pdf')
with pdf_file.open('rb') as pdf:
    message.add_attachment(
        pdf.read(), 'attachment', 'pdf', filename=pdf_file.name)

请注意我们如何再次需要二进制输入,以及message.add_attachment的第一个参数如何是包含有效负载的bytes object。

pathlib转移在这里不是绝对必要的,但显示了如何只键入一次文件名,并将其传递给add_attachmentfilename关键字参数,以便在此处使用相同的文件名,而无需目录部分。

如果您想将修改后的消息写入同一个文件,只需close文件句柄(或者更好,使用with open()...:在最初读取它时,因此您不必记住显式close() ,就像我上面做的那样)并打开阅读,然后写出新内容。 再次,记住使用二进制模式,并写出bytes

with open(filename, 'wb') as destination:
    destination.write(message.as_bytes())

模糊改编的演示: https://ideone.com/NBMOs1

顺便说一句,您的 SMTP 服务器不关心To: header 中的内容; 如果您sendmail me@example.org <Message.eml ,它将发送给我,而不是发送给To: header 中的任何人。 sendmail通常不安装在 Windows 上,但原理相同。)如果您担心的话,也许您实际上并不想要或不需要替换To: header。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM