ホームページ  >  記事  >  バックエンド開発  >  Python は電子メール モジュールを使用して電子メールをエンコードおよびデコードします

Python は電子メール モジュールを使用して電子メールをエンコードおよびデコードします

不言
不言オリジナル
2018-04-24 15:02:027642ブラウズ

この記事では、Python が電子メール モジュールを使用して電子メールをエンコードおよびデコードする方法について詳しく説明しています。同じニーズを持つ友人は参考にしてください。

電子メール モジュールは Python に付属しています。非常に興味深いもので、電子メールをエンコードおよびデコードすることができ、電子メールの処理に非常に役立ちます。
メールの処理、特にメールのデコードは非常に細かい作業です。なぜなら、メールの形式が大きく変わるからです。まずメールのソース ファイルを見てみましょう:


Received: from 192.168.208.56 ( 192.168.208.56 [192.168.208.56] ) by
ajax-webmail-wmsvr37 (Coremail) ; Thu, 12 Apr 2007 12:07:48 +0800 (CST)
Date: Thu, 12 Apr 2007 12:07:48 +0800 (CST)
From: user1 <xxxxxxxx@163.com>
To: zhaowei <zhaoweikid@163.com>
Message-ID: <31571419.200911176350868321.JavaMail.root@bj163app37.163.com>
Subject: =?gbk?B?u+nJtA==?=
MIME-Version: 1.0
Content-Type: multipart/Alternative; 
  boundary="----=_Part_21696_28113972.1176350868319"

------=_Part_21696_28113972.1176350868319
Content-Type: text/plain; charset=gbk
Content-Transfer-Encoding: base64

ztLS0b+qyrzS1M6qysfSu7j20MfG2ru70ru0zqOs1K3AtMrH0ru49tTCtffSu7TOztLDx8/W1NrT
prjDysew67XjssXE3MjI1ebC6bezICAg
------=_Part_21696_28113972.1176350868319
Content-Type: text/html; charset=gbk
Content-Transfer-Encoding: quoted-printable

<p>=CE=D2=D2=D1=BF=AA=CA=BC=D2=D4=CE=AA=CA=C7=D2=BB=B8=F6=D0=C7=C6=DA=BB=
=BB=D2=BB=B4=CE=A3=AC=D4=AD=C0=B4=CA=C7=D2=BB=B8=F6=D4=C2=B5=F7=D2=BB=B4=CE=
</p>
<p>=CE=D2=C3=C7=CF=D6=D4=DA=D3=A6=B8=C3=CA=C7=B0=EB=B5=E3=B2=C5=C4=DC=C8=
=C8</p>
<p>=D5=E6=C2=E9=B7=B3</p>
------=_Part_21696_28113972.1176350868319--

上記はメールのソースです。ファイルの最初の行から最初の空白行までがレターヘッダーで、その後がレター本文です。上記の情報をコピーし、xxx.eml という名前のファイルに保存します。もちろん、表示されるのは、Outlook がデコードしたバージョンです。

レターが xxx.eml として保存されていると仮定して、メール モジュールがこのメールをどのように処理するかを見てください。



#-*- encoding: gb2312 -*-
import email

fp = open("xxx.eml", "r")
msg = email.message_from_file(fp) # 直接文件创建message对象,这个时候也会做初步的解码
subject = msg.get("subject") # 取信件头里的subject, 也就是主题
# 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC?=这样的subject
h = email.Header.Header(subject)
dh = email.Header.decode_header(h)
subject = dh[0][0]
print "subject:", subject
print "from: ", email.utils.parseaddr(msg.get("from"))[1] # 取from
print "to: ", email.utils.parseaddr(msg.get("to"))[1] # 取to

fp.close()

このコードは、電子メールの件名、送信者、受信者を解析できます。 email.utils.parseaddr は電子メール アドレスを特別に解析するために使用されます。その理由は、電子メール アドレスは元のテキストで次のように記述されることが多いためです: user1 、email.utils.parseaddr はそれを In に解析できます。リストの最初の項目は user1、2 番目の項目は xxxxxxx@163.com です。ここでは次の部分のみを示します。

前のコードはレターヘッダーのみを解析し、次にレター本文を解析しました。レター本文には 2 つのプレーン テキスト部分と html 部分が含まれる場合があり、また添付ファイルが含まれる場合もあります。ここでは mime の知識が必要です。詳細な説明はオンラインでご覧いただけます。ここでは詳細には触れませんが、解析方法を見てみましょう:



#-*- encoding: gb2312 -*-
import email

fp = open("xxx.eml", "r")
msg = email.message_from_file(fp)

# 循环信件中的每一个mime的数据块
for par in msg.walk():
  if not par.is_multipart(): # 这里要判断是否是multipart,是的话,里面的数据是无用的,至于为什么可以了解mime相关知识。
    name = par.get_param("name") #如果是附件,这里就会取出附件的文件名
    if name:
      #有附件
      # 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC.rar?=这样的文件名
      h = email.Header.Header(name)
      dh = email.Header.decode_header(h)
      fname = dh[0][0]
      print &#39;附件名:&#39;, fname
      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(data)
      f.close()
    else:
      #不是附件,是文本内容
      print par.get_payload(decode=True) # 解码出文本内容,直接输出来就可以了。
    
    print &#39;+&#39;*60 # 用来区别各个部分的输出

メールを解析する複雑な機能を実現するのに、シンプルで、多くのコードは必要ありません。

電子メールのエンコード

電子メール モジュールを使用して電子メールを生成することも非常に簡単で、MIME の基本的な知識が必要なだけです。マイムの基本をいくつか見てみましょう。
MIME メッセージは、メッセージ ヘッダーとメッセージ本文の 2 つの部分で構成されます。メールでは、メール ヘッダーとメール本文です。電子メールのヘッダーと電子メール本文は空行で区切ります。これは、テキスト エディタ (メモ帳など) を使用して電子メールのソース ファイルを表示するとはっきりとわかります。 Outlook と Foxmail には、ソース ファイルを表示するための独自の機能があります。
メールヘッダーには、送信者、受信者、件名、時刻、MIME バージョン、メール内容の種類などの重要な情報が含まれています。それぞれの情報はドメインと呼ばれ、ドメイン名とその後に続く「:」と情報の内容で構成されます。これは 1 行である場合もあれば、複数行に及ぶ場合もあります。フィールドの最初の行は「top」と書く必要があります。つまり、左側に空白文字 (スペースとタブ) があってはなりません。継続行は空白文字で始まる必要があり、最初の空白文字はフィールドに固有のものではありません。情報そのもの。
メール本文にはメールの内容が含まれており、そのタイプはメールヘッダーの「Content-Type」フィールドで示されます。最も一般的なタイプは text/plain (プレーン テキスト) と text/html (ハイパーテキスト) です。電子メールの本文は複数のセグメントに分割されており、各セグメントにはセグメント ヘッダーとセグメント本文が含まれており、これらも空行で区切られています。一般的なマルチパート タイプには、マルチパート/混合、マルチパート/関連、およびマルチパート/代替の 3 つがあります。名前から、これらのタイプのそれぞれの意味と用途を推測するのは難しくありません。
電子メールに添付ファイルを追加する場合は、マルチパート/混合セグメントを定義する必要があります。埋め込みリソースがある場合は、少なくともマルチパート/関連セグメントを定義する必要があります。プレーン テキストとハイパーテキストが共存する場合は、少なくともマルチパート/代替セグメントを定義する必要があります。セグメントを定義する必要があります。メールを生成するということは、これらのさまざまな MIME パーツを生成することです。 email モジュールはこれらのプロセスをパッケージ化しています。生成メソッドを見てください:


#-*- encoding: gb2312 -*-
import email
import string, sys, os, email
import time

class MailCreator:
  def __init__(self):
    # 创建邮件的message对象
    self.msg = email.Message.Message()
    self.mail = ""  
    
  def create(self, mailheader, maildata, mailattachlist=[]):
    # mailheader 是dict类型,maildata是list, 且里面第一项为纯文本类型,第二项为html.
    # mailattachlist 是list, 里面为附件文件名
    if not mailheader or not maildata:
      return
    
    for k in mailheader.keys():
      # 对subject要作特殊处理,中文要转换一下。
      # 比如 "我的一个测试邮件" 就要转换为 =?gb2312?b?ztK1xNK7uPay4srU08q8/g==?=
      if k == &#39;subject&#39;:
        self.msg[k] = email.Header.Header(mailheader[k], &#39;gb2312&#39;)      
      else:
        self.msg[k] = mailheader[k]
    # 创建纯文本部分
    body_plain = email.MIMEText.MIMEText(maildata[0], _subtype=&#39;plain&#39;, _charset=&#39;gb2312&#39;)
    body_html = None
    # 创建html部分,这个是可选的
    if maildata[1]:
      body_html = email.MIMEText.MIMEText(maildata[1], _subtype=&#39;html&#39;, _charset=&#39;gb2312&#39;)
    
    
    # 创建一个multipart, 然后把前面的文本部分和html部分都附加到上面,至于为什么,可以看看mime相关内容
    attach=email.MIMEMultipart.MIMEMultipart()
    attach.attach(body_plain)
    if body_html:
      attach.attach(body_html)
    # 处理每一个附件
    for fname in mailattachlist:
      attachment=email.MIMEText.MIMEText(email.Encoders._bencode(open(fname,&#39;rb&#39;).read()))
      # 这里设置文件类型,全部都设置为Application.当然也可以是Image,Audio什么的,这里不管那么多
      attachment.replace_header(&#39;Content-type&#39;,&#39;Application/octet-stream;name="&#39;+os.path.basename(fname)+&#39;"&#39;)
      # 一定要把传输编码设置为base64,因为这里默认就是用的base64
      attachment.replace_header(&#39;Content-Transfer-Encoding&#39;, &#39;base64&#39;)
      attachment.add_header(&#39;Content-Disposition&#39;,&#39;attachment;filename="&#39;+os.path.basename(fname)+&#39;"&#39;)
      attach.attach(attachment)
    # 生成最终的邮件      
    self.mail = self.msg.as_string()[:-1] + attach.as_string()
    
    return self.mail

if __name__ == &#39;__main__&#39;:
  mc = MailCreator()
  header = {&#39;from&#39;: &#39;zhaowei@163.com&#39;, &#39;to&#39;:&#39;weizhao@163.com&#39;, &#39;subject&#39;:&#39;我的一个测试邮件&#39;}
  data = [&#39;plain text information&#39;, &#39;<font color="red">html text information</font>&#39;]
  if sys.platform == &#39;win32&#39;:
    attach = [&#39;c:/windows/clock.avi&#39;]
  else:
    attach = [&#39;/bin/cp&#39;]
  
  mail = mc.create(header, data, attach)
  
  f = open("test.eml", "wb")
  f.write(mail)
  f.close()

ここでは、処理を行うためのクラスをカプセル化しています:

1. まずメッセージ オブジェクトを作成します。 Message.Message()

2. MIMEMultipart オブジェクトを作成します: email.MIMEMultipart.MIMEMultipart()
3. 各 MIMEText オブジェクトを作成し、MIMEText は実際にはテキストだけでなく、画像、アプリケーション、オーディオなども追加します。の上。
4. 最終メールを生成します。

関連する推奨事項:


指定されたパスの下にあるすべてのディレクトリのサイズを計算する Python スクリプト_PHP チュートリアル

文字幅を計算する Python メソッド

以上がPython は電子メール モジュールを使用して電子メールをエンコードおよびデコードしますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。