ホームページ > バックエンド開発 > Python チュートリアル > 電子メール、smtplib、poplib、imaplib モジュールを使用して Python で電子メールを送受信する方法

電子メール、smtplib、poplib、imaplib モジュールを使用して Python で電子メールを送受信する方法

PHPz
リリース: 2023-05-16 23:44:26
転載
1730 人が閲覧しました

メールの流れは次のとおりです:

  • メール ユーザー エージェント (MUA) は、ユーザーが自分のメール アカウントにアクセスするために使用するメール クライアントまたはソフトウェアを指します。 (つまり、Outlook に似た電子メール ソフトウェア)

  • MTA: メール転送エージェント -- メール転送エージェントは、NetEase、Sina などの電子メール サービス プロバイダーです。

  • MDA: メール配信エージェント——メール配信エージェント。電子メール サービス プロバイダーのサーバー

送信者-> MUA -> MTA -> MTA -> 複数の MTA -> MDA

は電子メールを送受信するプログラムを作成する必要があります。これは本質的に次のとおりです。

  • MTA に電子メールを送信するための MUA を作成します;

  • MDA からのメールを受信するには MUA を書き込みます。

電子メールを送信する場合、MUA と MTA で使用されるプロトコルは SMTP (Simple Mail Transfer Protocol) であり、後続の MTA も別の MTA に対して SMTP プロトコルを使用します。

電子メールを受信するとき、MUA と MDA は 2 つのプロトコルを使用します: POP: ポスト オフィス プロトコル、現在のバージョンは 3 (一般に POP3 として知られています)、IMAP: インターネット メッセージ アクセス プロトコル、現在のバージョンは 4、利点は次のとおりです。メールを受信できるだけでなく、MDA に保存されているメールを受信トレイからゴミ箱に移動するなど、直接操作することもできます。

1. SMTP (Simple Mail Transfer Protocol)

は、Simple Mail Transfer Protocol で、送信元アドレスから宛先アドレスにメールを送信するための一連のルールであり、配信を制御します。文字のトランジットモード。

Python の smtplib は、電子メールを送信するための非常に便利な方法を提供します。これは単に SMTP プロトコルをカプセル化するだけです。

Python は、smtplibemail という 2 つのモジュールで SMTP をサポートします。email は電子メールの構築を担当し、smtplibメールの送信を担当します。

1. 電子メールの構築: email.mime タイプ

電子メール オブジェクトの構築は、Messag オブジェクトです。MIMEText オブジェクトを構築する場合、これは、テキスト メール オブジェクトを意味します。MIMEImage オブジェクトを作成すると、添付ファイルとして画像が表示されます。複数のオブジェクトを組み合わせるには、MIMEMultipart オブジェクトと MIMEBase# を使用します。 ##任意のオブジェクトを表すことができます。それらの継承関係は次のとおりです。

Message
+- MIMEBase
   +- MIMEMultipart
   +- MIMENonMultipart
      +- MIMEMessage
      +- MIMEText
      +- MIMEImage
ログイン後にコピー

まず、最も単純なプレーン テキストの電子メールを作成し、それを SMTP 経由で送信します。

from email.mime.text import MIMEText
msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
ログイン後にコピー

MIMEText オブジェクトを構築するとき、最初のパラメータは電子メール本文、2 番目のパラメータは MIME のサブタイプであることに注意してください。'plain' を渡します。そして最後に、MIME は 'text/plain' であり、最後に、多言語互換性を確保するために utf-8 エンコーディングを使用する必要があります。

2. SMTP オブジェクトの作成

構文は次のとおりです:

import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
ログイン後にコピー

パラメータの説明:

  • host: SMTP サーバーのホスト。このパラメータはオプションで、必要に応じてホストの IP アドレスまたはドメイン名を指定できます (例: runoob.com)。

  • port: host パラメーターを指定する場合は、SMTP サービスで使用されるポート番号を指定する必要があります。通常、SMTP ポート番号は 25 です。

  • local_hostname: SMTP がローカル マシン上にある場合は、サーバー アドレスを localhost として指定するだけで済みます。

3. Python SMTP オブジェクトは、sendmail メソッドを使用して電子メールを送信します

構文は次のとおりです:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])
ログイン後にコピー

パラメータの説明:

  • from_addr: 電子メール送信者のアドレス。

  • to_addrs: 文字列リスト、電子メール送信アドレス。

  • msg: メッセージの送信

ここの 3 番目のパラメータに注意してください。msg は電子メールを表す文字列です。電子メールには通常、タイトル、送信者、受信者、電子メールの内容、添付ファイルなどが含まれるため、電子メールを送信するには情報の形式に注意する必要があります。この形式は、smtp プロトコルで定義されている形式です。

2. 例

2: SMTP をサポートするサービスがこのマシンにインストールされています

次の実行例では、SMTP をサポートするサービスがマシンにインストールされている必要があります。機械。

sendmail()このメソッドは電子メールを送信するもので、一度に複数の人に送信できるため、list が渡され、電子メールが送信されます。 body は stras_string()MIMEText オブジェクトを str に変換します。

Header オブジェクトによってエンコードされたテキストには、UTF-8 エンコード情報と Base64 エンコードされたテキストが含まれています。

次は、Python を使用して電子メールを送信する簡単な例です:

import smtplib
from email.mime.text import MIMEText
from email.header import Header
 
sender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
 
# 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码
message = MIMEText('Python 邮件发送测试内容...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')   # 发送者
message['To'] =  Header("测试", 'utf-8')        # 接收者
message['Subject'] = Header('Python SMTP 邮件测试主题', 'utf-8')
 
try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print "邮件发送成功"
except smtplib.SMTPException:
    print "Error: 无法发送邮件"
ログイン後にコピー

2. サードパーティの SMTP サービスの使用

ローカルに sendmail アクセスがない場合は、サービス プロバイダー (QQ、NetEase、Google など) からの他の電子メール SMTP アクセスを使用することもできます。

login()SMTP サーバーへのログインに使用されるメソッド

受信者の名前は、

Mr Green ## などのフレンドリ名として表示されません。 # ;formataddr メソッドを使用して電子メール アドレスをフォーマットします。中国語が含まれている場合は、

Header

オブジェクトを通じてエンコードする必要があります。

msg['To']

はリストではなく文字列を受け取ります。複数の電子メール アドレスがある場合は、 を使用して区切ってください。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:py;">import smtplib from email.mime.text import MIMEText from email.utils import formataddr # 第三方 SMTP 服务 mail_host = &quot;mail.sss.com&quot; # 设置服务器 mail_user = &quot;it_system@sss.com&quot; # 用户名 mail_pass = &quot;Ssss201709#&quot; # 口令 sender = &amp;#39;it_system@tcl.com&amp;#39; receivers = &amp;#39;sss.yang@tcsssl.com&amp;#39; # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 message = MIMEText(&amp;#39;Python 邮件内容测试...&amp;#39;, &amp;#39;plain&amp;#39;, &amp;#39;utf-8&amp;#39;) message[&amp;#39;From&amp;#39;] = formataddr((&amp;#39;SCBC-啊iT&amp;#39;, sender)) message[&amp;#39;To&amp;#39;] = formataddr((&amp;#39;杨生&amp;#39;, receivers)) message[&amp;#39;Subject&amp;#39;] = &amp;#39;Python SMTP 邮件测试&amp;#39; try: smtpObj = smtplib.SMTP() smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号 smtpObj.login(mail_user, mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) print(&quot;邮件发送成功&quot;) except smtplib.SMTPException: print(&quot;Error: 无法发送邮件&quot;)</pre><div class="contentsignin">ログイン後にコピー</div></div><h4>3、使用Python发送HTML格式的邮件</h4><p>Python在构造<code>MIMEText对象时,把HTML字符串传进去,再把第二个参数由plain变为html就可以了:

具体代码如下:

mail_msg = """
Python 邮件内容测试...


这是一个链接


"""
message = MIMEText(mail_msg, &#39;html&#39;, &#39;utf-8&#39;)
ログイン後にコピー

4、Python 发送带附件的邮件

带附件的邮件可以看做包含若干部分的邮件:文本和各个附件本身,所以,可以构造一个MIMEMultipart对象代表邮件本身,然后往里面加上一个MIMEText作为邮件正文,再继续往里面加上表示附件的MIMEBase对象即可。

发送带附件的邮件,首先要创建MIMEMultipart()实例,然后构造附件,如果有多个附件,可依次构造,最后利用smtplib.smtp发送。

from email.mime.multipart import MIMEMultipart

# 创建一个带附件的实例
message = MIMEMultipart()

message[&#39;From&#39;] = formataddr((&#39;SCBC-啊iT&#39;, sender))
message[&#39;To&#39;] = formataddr((&#39;杨生&#39;, receivers))
message[&#39;Subject&#39;] = &#39;Python SMTP 邮件测试&#39;

mail_msg = """
Python 邮件内容测试...


这是一个链接


"""
# 邮件正文内容
message.attach(MIMEText(mail_msg, &#39;html&#39;, &#39;utf-8&#39;))

# 构造附件1,传送当前目录下的 test.txt 文件
att = MIMEText(open(&#39;32.txt&#39;, &#39;rb&#39;).read(), &#39;base64&#39;, &#39;utf-8&#39;)
att["Content-Type"] = &#39;application/octet-stream&#39;
# 这里的filename可以任意写,写什么名字,邮件中显示什么名字
att["Content-Disposition"] = &#39;attachment; filename="32.txt"&#39;
message.attach(att)
ログイン後にコピー

5、在 HTML 文本中添加图片

要把图片嵌入到邮件正文中,我们只需按照发送附件的方式,先把邮件作为附件添加进去,然后,在HTML中通过引用src="cid:0"就可以把附件作为图片嵌入了。如果有多个图片,给它们依次编号,然后引用不同的cid:x即可。

邮件的 HTML 文本中一般邮件服务商添加外链是无效的,正确添加图片的实例如下所示:

from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

# 创建一个带附件的实例
message = MIMEMultipart()

message[&#39;From&#39;] = formataddr((&#39;SCBC-啊iT&#39;, sender))
message[&#39;To&#39;] = formataddr((&#39;杨生&#39;, receivers))
message[&#39;Subject&#39;] = &#39;Python SMTP 邮件测试&#39;

mail_msg = """
Python 邮件内容测试...


这是一个链接


图片演示:





"""
# 邮件正文内容
message.attach(MIMEText(mail_msg, &#39;html&#39;, &#39;utf-8&#39;))

# 指定图片为当前目录
with  open(&#39;a.jpg&#39;, &#39;rb&#39;) as fp:
    msgImage = MIMEImage(fp.read())

# 定义图片 ID,在 HTML 文本中引用
msgImage.add_header(&#39;Content-ID&#39;, &#39;&#39;)
message.attach(msgImage)
ログイン後にコピー

或者通过MIMEBase来添加图片

# 指定图片为当前目录
with  open(&#39;a.jpg&#39;, &#39;rb&#39;) as fp:
    # 设置附件的MIME和文件名,这里是png类型:
    mime = MIMEBase(&#39;image&#39;, &#39;jpg&#39;, filename=&#39;a.jpg&#39;)
    # 加上必要的头信息:
    mime.add_header(&#39;Content-Disposition&#39;, &#39;attachment&#39;, filename=&#39;附件显示名称.jpg&#39;)
    mime.add_header(&#39;Content-ID&#39;, &#39;&#39;)  # 如果有多个文件需要使用.format(index)
    mime.add_header(&#39;X-Attachment-Id&#39;, &#39;0&#39;)  # 如果有多个文件需要使用.format(index)
    # 把附件的内容读进来:
    mime.set_payload(fp.read())
    # 用Base64编码:
    encoders.encode_base64(mime)
    # 添加到MIMEMultipart:
    message.attach(mime)
ログイン後にコピー

6、同时支持HTML和Plain格式

如果我们发送HTML邮件,收件人通过浏览器或者Outlook之类的软件是可以正常浏览邮件内容的,但是,如果收件人使用的设备太古老,查看不了HTML邮件怎么办?

办法是在发送HTML的同时再附加一个纯文本,如果收件人无法查看HTML格式的邮件,就可以自动降级查看纯文本邮件。

利用MIMEMultipart就可以组合一个HTML和Plain,要注意指定subtype是alternative

msg = MIMEMultipart(&#39;alternative&#39;)
msg[&#39;From&#39;] = ...
msg[&#39;To&#39;] = ...
msg[&#39;Subject&#39;] = ...

msg.attach(MIMEText(&#39;hello&#39;, &#39;plain&#39;, &#39;utf-8&#39;))
msg.attach(MIMEText(&#39;Hello&#39;, &#39;html&#39;, &#39;utf-8&#39;))
# 正常发送msg对象...
ログイン後にコピー

7、加密SMTP

如果使用标准的25端口连接SMTP服务器发送邮件,即使身份验证成功,因为明文传输的缘故,整个邮件发送过程都有可能被窃听。要更安全地发送邮件,可以加密SMTP会话,实际上就是先创建SSL安全连接,然后再使用SMTP协议发送邮件。

在某些邮件服务提供商(例如Gmail)中,SMTP服务必须使用加密传输。我们来看看如何通过Gmail提供的安全SMTP发送邮件。

只需要在创建SMTP对象后,立刻调用starttls()方法,就创建了安全连接。后面的代码和前面的发送邮件代码完全一样。

必须知道,Gmail的SMTP端口是587,因此,修改代码如下:

smtp_server = &#39;smtp.gmail.com&#39;
smtp_port = 587
server = smtplib.SMTP(smtp_server, smtp_port)
server.starttls()
# 剩下的代码和前面的一模一样:
server.set_debuglevel(1)
ログイン後にコピー

三、使用poplib接收邮件

收取邮件就是编写一个MUA作为客户端,从MDA把邮件获取到用户的电脑或者手机上。收取邮件最常用的协议是POP协议,目前版本号是3,俗称POP3

Python内置一个poplib模块,实现了POP3协议,可以直接用来收邮件。

POP3 的命令和响应数据都是基于 ASCII 文本的,并以 CR 和 LF(/r/n) 作为行结束符,响应数据包括一个表示返回状态的符号(+/)和描述信息。

请求和响应的标准格式如下:

请求标准格式:命令 [参数] CRLF
响应标准格式:+OK /[-ERR] description CRLF

POP3 协议客户端的命令和服务器端对应的响应数据如下:

  • user name:向 POP 服务器发送登录的用户名。

  • pass string:向 POP 服务器发送登录的密码。

  • quit:退出 POP 服务器。

  • stat:统计邮件服务器状态,包括邮件数和总大小。

  • list [msg_no]:列出全部邮件或指定邮件。返回邮件编号和对应大小。

  • retr msg_no:获取指定邮件的内容(根据邮件编号来获取,编号从 1 开始)。

  • dele msg_no:删除指定邮件(根据邮件编号来删除,编号从 1 开始)。

  • noop:空操作。仅用于与服务器保持连接。

  • rset:用于撤销 dele 命令。

poplib 模块完全模拟了上面命令,poplib.POP3 或 poplib.POP3_SSL 为上面命令提供了相应的方法,开发者只要依次使用上面命令即可从服务器端下载对应的邮件

注意到POP3协议收取的不是一个已经可以阅读的邮件本身,而是邮件的原始文本,这和SMTP协议很像,SMTP发送的也是经过编码后的一大段文本。

要把POP3收取的文本变成可以阅读的邮件,还需要用email模块提供的各种类来解析原始文本,变成可阅读的邮件对象。

所以,收取邮件分两步:

第一步:使用poplib.POP3 或 poplib.POP3_SSL 按 POP3 协议把邮件的原始文本下载到本地;

用POP3获取邮件其实很简单,要获取所有邮件,只需要循环使用retr()把每一封邮件内容拿到即可。真正麻烦的是把邮件的原始内容解析为可以阅读的邮件对象。

import poplib
from email.parser import Parser
# email.parser 解析电子邮件,返回这个对象的email.message.Message实例
from email.header import decode_header
from email.utils import parseaddr

# 服务器及用户信息
host = &#39;mail.tcl.com&#39;
username = &#39;bobin.yang@tcl.com&#39;
password = &#39;Ybb7654321&#39;

# 连接到POP3服务器
conn = poplib.POP3_SSL(host)
# 注意qq邮箱使用SSL连接
# 设置调试模式,可以看到与服务器的交互信息
conn.set_debuglevel(1)

# 打印POP3服务器的欢迎文字
print(conn.getwelcome().decode("utf-8"))

# 身份认证
conn.user(username)
conn.pass_(password)

# 获取服务器上信件信息,返回一个列表,第一项是一共有多少封邮件,第二项是共有多少字节
# stat()返回邮件数量和占用空间
mail_total, total_size = conn.stat()
print(&#39;message: %s.Size:%s&#39; % (mail_total, total_size))

# list()返回(response, [&#39;mesg_num octets&#39;, ...], octets),第二项是编号
resp, mails, octets = conn.list()
print(mails)
# 返回的列表类似[b&#39;1 82923&#39;, b&#39;2 2184&#39;, ...]

# 获取最新一封邮件,注意索引号从1开始
# POP3.retr(which) 检索序号which的这个邮件,然后设置他的出现标志 返回(response, [&#39;line&#39;, ...], octets)这个三元组
resp, lines, ocetes = conn.retr(len(mails))
print(&#39;lines:&#39;, len(lines))
# lines 存储了邮件的原始文本的每一行
# 可以获得整个邮件的原始文本
print("-------------------")
ログイン後にコピー

第二步:使用 email.parser.Parser或BytesParser 解析邮件内容为消息对象,然后,用适当的形式把邮件内容展示给用户即可。

解析邮件的过程和上一节构造邮件正好相反。

程序在创建 BytesParser(解析字节串格式的邮件数据)或 Parser(解析字符串格式的邮件数据)时,必须指定 policy=default;否则,BytesParse 或 Parser 解析邮件数据得到的就是过时的 Message 对象,,不是新的 EmailMessage,处理起来非常不方便。

1、使用 email.parser.Parser解析邮件内容为 email.message.Message(过时,不推荐)
msg = b&#39;\r\n&#39;.join(lines).decode(&#39;utf-8&#39;)
# 解析出邮件
msg = Parser().parsestr(msg)


# email.Parser.parsestr(text, headersonly=False)
# 与parser()方法类似,不同的是他接受一个字符串对象而不是一个类似文件的对象
# 可选的headersonly表示是否在解析玩标题后停止解析,默认为否
# 返回根消息对象

# 编码处理,文本邮件的内容也是str,还需要检测编码,否则,非UTF-8编码的邮件都无法正常显示
def guess_charset(msg):
    charset = msg.get_charset()  # 从msg对象获取编码
    if charset is None:
        content_type = msg.get(&#39;Content-Type&#39;, &#39;&#39;).lower()  # 如果获取不到,再从content—type字段获取
        if &#39;charset&#39; in content_type:
            charset = content_type.split(&#39;charset=&#39;)[1].strip()
            return charset
    return charset


# 数据解码,邮件的Subject或者Email中包含的名字都是经过编码后的str,要正常显示,就必须decode
def decode_str(s):
    value, charset = decode_header(s)[0]  # 数据,数据编码方式,from email.header import decode_header
    # decode_header()返回一个list,因为像Cc、Bcc这样的字段可能包含多个邮件地址,所以解析出来的会有多个元素。上面的代码我们偷了个懒,只取了第一个元素。
    if charset:
        value = value.decode(charset)
    return value


# print_ingo函数:解析邮件与构造邮件的步骤正好相反
def print_info(msg, indent=0):  # indent用于缩进显示
    if indent == 0:
        for header in [&#39;From&#39;, &#39;To&#39;, &#39;Subject&#39;]:  # 邮件的from、to、subject存在于根对象上
            value = msg.get(header, &#39;&#39;)
            if value:
                if header == &#39;Subject&#39;:
                    value = decode_str(value)  # 需要解码subject字符串
                else:
                    # 解码mail地址
                    hdr, addr = parseaddr(value)
                    name = decode_str(hdr)
                    value = &#39;%s&#39; % addr
            print(&#39;%s:  %s  %s&#39; % (header, value, name))
            print(&#39;-*-&#39; * 20)
    if msg.is_multipart():
        # 如果邮件对象是一个is_multipart,get_payload()返回一个list,包含所有子对象
        parts = msg.get_payload()  # 循环获得列表项
        for n, part in enumerate(parts):
            # print(&#39;%spart %s&#39; % (&#39;  &#39; * indent, n))
            # print(&#39;%s------------&#39; % (&#39;  &#39; * indent))
            # 递归打印没一个子对象
            print_info(part, indent + 1)
    else:
        # 邮件对象不是一个is_multipart,就根据content_type判断
        content_type = msg.get_content_type()  # 数据类型
        if content_type == &#39;text/plain&#39; or content_type == &#39;text/html&#39;:  # 纯文本 html文本
            # 纯文本或html内容
            content = msg.get_payload(decode=True)  # 获得文本对象的字符串而非对象本身
            charset = guess_charset(msg)  # 要检测文本编码
            if charset: content = content.decode(charset)
            content = &#39;%s&#39; % (content)
            print(content)  # 获取邮件文本内容,如果只有文本,打印显示的结果和邮件中看的效果一模一样
        else:
            print(content_type+&#39;不是文本&#39;)


print_info(msg, 0)

# 退出
conn.quit()
ログイン後にコピー
2、使用email.parser.BytesParser 解析成email.message.EmailMessage对象

如果程序要获取邮件的发件人、收件人和主题,直接通过 EmailMessage 的相应属性来获取即可,与前面为 EmailMessage 设置发件人、收件人和主题的方式是对应的。
如果程序要读取 EmailMessage 的各部分,则需要调用该对象的 walk() 方法,该方法返回一个可迭代对象,程序使用 for 循环遍历 walk() 方法的返回值,对邮件内容进行逐项处理:

  • 如果邮件某项的 maintype 是 'multipart',则说明这一项是容器,用于包含邮件内容、附件等其他项。

  • 如果邮件某项的 maintype 是 'text',则说明这一项的内容是文本,通常就是邮件正文或文本附件。对于这种文本内容,程序直接将其输出到控制台中。

  • 如果邮件中某个项的 maintype 属性是“其他”,那么这一项的内容就是作为附件的,程序会将附件内容保存到本地文件中。

import os
import poplib
import mimetypes
from email.parser import Parser, BytesParser
from email.policy import default

msg_data = b&#39;\r\n&#39;.join(lines)
# 将字符串内容解析成邮件,此处一定要指定policy=default
msg = BytesParser(policy=default).parsebytes(msg_data)
print(type(msg))

print(&#39;发件人:&#39; + msg[&#39;from&#39;])
print(&#39;收件人:&#39; + msg[&#39;to&#39;])
print(&#39;主题:&#39; + msg[&#39;subject&#39;])
print(&#39;第一个收件人名字:&#39; + msg[&#39;to&#39;].addresses[0].username)
print(&#39;第一个发件人名字:&#39; + msg[&#39;from&#39;].addresses[0].username)
for part in msg.walk():
    counter = 1
    # 如果maintype是multipart,说明是容器(用于包含正文、附件等)
    if part.get_content_maintype() == &#39;multipart&#39;:
        continue
    # 如果maintype是multipart,说明是邮件正文部分
    elif part.get_content_maintype() == &#39;text&#39;:
        print(part.get_content())
    # 处理附件
    else:
        # 获取附件的文件名
        filename = part.get_filename()
        # 如果没有文件名,程序要负责为附件生成文件名
        if not filename:
            # 根据附件的contnet_type来推测它的后缀名
            ext = mimetypes.guess_extension(part.get_content_type())
            # 如果推测不出后缀名
            if not ext:
                # 使用.bin作为后缀名
                ext = &#39;.bin&#39;
            # 程序为附件来生成文件名
            filename = &#39;part-%03d%s&#39; % (counter, ext)
        counter += 1
        # 将附件写入的本地文件
        with open(os.path.join(&#39;.&#39;, filename), &#39;wb&#39;) as fp:
            fp.write(part.get_payload(decode=True))
# 退出服务器,相当于发送POP 3的quit命令
conn.quit()
ログイン後にコピー

四、利用imaplib读取邮件文本内容及附件内容

通过IMAP协议来管理邮箱用的,称作交互邮件访问协议。

! encoding:utf8
&#39;&#39;&#39;
环境:
    Win10 64位 Python 2.7.5
参考:
    http://www.pythonclub.org/python-network-application/email-format
    http://blog.sina.com.cn/s/blog_4deeda2501016eyf.html
&#39;&#39;&#39;


import imaplib
import email


def parseHeader(message):
    """ 解析邮件首部 """
    subject = message.get(&#39;subject&#39;)  
    h = email.Header.Header(subject)
    dh = email.Header.decode_header(h)
    subject = unicode(dh[0][0], dh[0][1]).encode(&#39;gb2312&#39;)
    # 主题
    print subject
    print &#39;
&#39;
    # 发件人
    print &#39;From:&#39;, email.utils.parseaddr(message.get(&#39;from&#39;))[1]
    print &#39;
&#39;
    # 收件人
    print &#39;To:&#39;, email.utils.parseaddr(message.get(&#39;to&#39;))[1]
    print &#39;
&#39;
    # 抄送人
    print &#39;Cc:&#39;,email.utils.parseaddr(message.get_all(&#39;cc&#39;))[1]



def parseBody(message):
    """ 解析邮件/信体 """
    # 循环信件中的每一个mime的数据块
    for part in message.walk():
        # 这里要判断是否是multipart,是的话,里面的数据是一个message 列表
        if not part.is_multipart():
            charset = part.get_charset()
            # print &#39;charset: &#39;, charset
            contenttype = part.get_content_type()
            # print &#39;content-type&#39;, contenttype
            name = part.get_param("name") #如果是附件,这里就会取出附件的文件名
            if name:
                # 有附件
                # 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC.rar?=这样的文件名
                fh = email.Header.Header(name)
                fdh = email.Header.decode_header(fh)
                fname = dh[0][0]
                print &#39;附件名:&#39;, fname
                # attach_data = par.get_payload(decode=True) # 解码出附件数据,然后存储到文件中

                # try:
                #     f = open(fname, &#39;wb&#39;) #注意一定要用wb来打开文件,因为附件一般都是二进制文件
                # except:
                #     print &#39;附件名有非法字符,自动换一个&#39;
                #     f = open(&#39;aaaa&#39;, &#39;wb&#39;)
                # f.write(attach_data)
                # f.close()
            else:
                #不是附件,是文本内容
                print part.get_payload(decode=True) # 解码出文本内容,直接输出来就可以了。
                # pass
            # print &#39;+&#39;*60 # 用来区别各个部分的输出


def getMail(host, username, password, port=993):
    try:
        serv = imaplib.IMAP4_SSL(host, port)
    except Exception, e:
        serv = imaplib.IMAP4(host, port)

    serv.login(username, password)
    serv.select()
    # 搜索邮件内容
    typ, data = serv.search(None, &#39;(FROM "xx@xxx.com")&#39;)

    count = 1
    pcount = 1
    for num in data[0].split()[::-1]:
        typ, data = serv.fetch(num, &#39;(RFC822)&#39;)
        text = data[0][1]
        message = email.message_from_string(text)   # 转换为email.message对象
        parseHeader(message)
        print &#39;
&#39;
        parseBody(message)   
        pcount += 1
        if pcount > count:
            break

    serv.close()
    serv.logout()


if __name__ == &#39;__main__&#39;:
    host = "imap.mail_serv.com" # "pop.mail_serv.com"
    username = "Trevor@mail_serv.com"
    password = "your_password"
    getMail(host, username, password)
ログイン後にコピー

以上が電子メール、smtplib、poplib、imaplib モジュールを使用して Python で電子メールを送受信する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート