2017-03-16 10 views
2

私はperlの初心者であり、Email :: MIMEを使ってマルチパートで正しく電子メールを解析する方法を理解しています。私は、私の現在の努力が正しく読むことができなかった別の組み合わせを特定しました。Email :: MIMEとmultipart/subpartと混合した電子メールを解析する

 Content-Type: multipart/mixed; boundary="===============1811908679642194059==" 
MIME-Version: 1.0 

This is an OpenPGP/MIME signed message (RFC 4880 and 3156) 
--===============1811908679642194059== 
Content-Type: multipart/signed; micalg=pgp-sha256; 
    protocol="application/pgp-signature"; 
    boundary="lGJM242FL2E9Wh4auTNwQRWOeFI0Wj9mB" 

This is an OpenPGP/MIME signed message (RFC 4880 and 3156) 
--lGJM242FL2E9Wh4auTNwQRWOeFI0Wj9mB 
Content-Type: multipart/alternative; 
    boundary="------------CC2F0C038668F58F6EDEA0D2" 

This is a multi-part message in MIME format. 
--------------CC2F0C038668F58F6EDEA0D2 
Content-Type: text/plain; charset=windows-1252 
Content-Transfer-Encoding: quoted-printable 

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= 
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= 
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 

text/plainの部分は、私がしたい部分ですが、「テキスト」コンポーネントを読み込むことはちょうど私に「これはマルチパートである...」の行を与え、それはそれです。これは私が類似のサブパートを持つ他の電子メールを読むために開発したコードですが、これを正しく解釈しません。

それは、電子メールの一部として「身体」機能に関係することになりそうだ:: MIME:

This decodes and returns the body of the object as a byte string. For 
top-level objects in multi-part messages, this is highly likely to be 
something like "This is a multi-part message in MIME format." 

メール内で使用するために適切な機能である何:: MIMEが正しくこのコンテンツタイプを読み取るために?

このメールのコンテンツタイプを正しく特定するにはどうすればよいですか?それは "multipart/mixed"か "text/plain"か "multipart/alternative"ですか?

ここでもサブパーツメソッドを使用したいですか?

my @mailData; 
my $msg = Email::MIME->new($buf); 
foreach my $part ($msg->subparts) { 
    foreach my $sub_part ($part->subparts) { 
     print $sub_part->content_type; 
     if ($sub_part->content_type =~ m!text!) { 
      @mailData = split('\n', $sub_part->body); 
     } 
    } 
} 

上記のコードは、@mailData配列の「これは複数の部分のメッセージです...」と表示しています。

+0

コードを追加しました。ありがとう。 –

+1

誰もこれを試してみたことがないので、私はそれを行かせます。あなたのテキストメッセージの第2レベルの「部品」だけを見ているようです。たぶん、walk_partsメソッドを使用して電子メールのすべての部分を処理しますか?それぞれのタイプと本文を印刷して、あなたのコンテンツがどこにあるかを知ることができます。うまくいけば、あなたの電子メールに何が起こっているのかをもっと分かりやすく伝えてください。 – FrankRalphBob

+0

私が学んだのは、私のコードはtext/asciiパーツのうちの1つしか表示しない(アクセスすることができる)のに対し、walk_partsはすべてのパーツにアクセスできることです。私はまだこれが適切な方法であると完全には分からない。 –

答えて

1

私は数日の電子メールの処理を自動化するために、Email :: MIME、MIME :: Parser、MIME :: Entityを扱っていました。私は同じ電子メールをエンコードする標準的な方法がほとんどないことを知ったので、思ったよりもはるかに難しいものでした。

これは、電子メールのヘッダーと本文の両方を処理するかなり信頼できる方法です。道に沿って手伝ってくれたすべての人に感謝します。

#!/usr/bin/perl -w 

use strict; 
use MIME::Parser; 
use MIME::Entity; 
use Email::MIME; 

# Read the email from STDIN 
my $buf; 
while(<STDIN>){ 
     $buf .= $_; 
} 

# This creates msg-NNNN-N.txt and signature-N.asc files 
# and I don't know why. Related to output_to_core? 
my $parser = MIME::Parser->new; 
$parser->extract_uuencode(1); 
$parser->extract_nested_messages(1); 
$parser->output_to_core(0); 

# For reading headers 
my $entity = $parser->parse_data($buf); 

# For reading the body (of an mbox) 
my $msg = Email::MIME->new($buf); 

# Use MIME::Entity to read various headers. 
my $subject = $entity->head->get('Subject'); 
my $from = $entity->head->get('From'); 
my $AdvDate = $entity->head->get('Date'); 
$AdvDate =~ s/\n//g; $subject =~ s/\n//g; $from =~ s/\n//g; 

print "Subject: $subject\n"; 
print "From: $from\n"; 
print "Date: $AdvDate\n"; 

my @mailData; 

    # walk through all the different attachments. Stop at the first one that matches and 
    # read its contents into mailData. The first one typically appeared to be the primary one. 
    $msg->walk_parts(sub { 
     my ($part) = @_; 
     #warn($part->content_type . ": " . $part->subparts); 
     if (($part->content_type =~ /text\/plain; charset=\"?utf-8\"?/i) && [email protected]) { 
     #print $part->body; 
     @mailData = split('\n', $part->body); 
     } 
     elsif (($part->content_type =~ /text\/plain; charset=\"?us-ascii\"?/i) && [email protected]) { 
     #print $part->body; 
     @mailData = split('\n', $part->body); 
     } 
     elsif (($part->content_type =~ /text\/plain; charset=\"?windows-1252\"?/i) && [email protected]) { 
     #print $part->body; 
     @mailData = split('\n', $part->body); 
     } 
     elsif (($part->content_type =~ /text\/plain; charset=\"?iso-8859-1\"?/i) && [email protected]) { 
     #print $part->body; 
     @mailData = split('\n', $part->body); 
     } 
    }); 


# manipulate the body of the message stored in mailData 
foreach my $line (@mailData) { 
     print "$line\n"; 
} 
関連する問題