使用Perl解析多部分/替代电子邮件

3

我正在寻找一种方法来解析multipart/alternative电子邮件的正文文本部分。我目前有一个使用Email::Mime模块的Perl脚本,可以正确解析text/plain和text/html。但是我遇到的问题是,当我解析multipart/alternative电子邮件时,$part->body总是返回空值。我尝试使用$part->body_raw,它确实返回了文本��容,但它包括我需要省略的标题。

使用$part->data_raw的当前输出

--_000_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable 

Text Body 

期望的输出

Text Body

PERL代码

my ( $body, $text_body, $html_body, $multi_body );
for my $part (@parts) {

if ( $part->content_type =~ m!text/html! ) {
    my $hs = HTML::Strip->new( emit_spaces => 0 );
    $html_body .= $hs->parse( $part->body );
    print "Found HTML\n";
}
elsif ($part->content_type =~ m!text/plain!
    or $part->content_type eq '' )
{

    $text_body .= $part->body;
    print "Found TEXT\n";
}
elsif ($part->content_type =~ m!multipart/alternative!
    or $part->content_type eq '' )
{
    print "Found Multipart\n";
    $multi_body .= $part->body;     

}

来源

Content-Type: multipart/related;
boundary="_004_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_";
type="multipart/alternative"
MIME-Version: 1.0

--_004_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_
Content-Type: multipart/alternative;
boundary="_000_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_"

--_000_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Test Body

body_str (https://metacpan.org/pod/Email::MIME#body_str) 是什么?你能发布你正在使用的代码和消息源,以便其他人可以复制你的结果吗? - Oesor
这是代码,我已经尝试了body_str,但返回的结果是——>无法将multipart/alternative的正文作为字符串获取;boundary="000_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0"位于/Library/Perl/5.16/Email/MIME.pm的第341行,<>行1。 - Mark
2个回答

5
多部分包含多个部分。对它们进行迭代:
use strict;
use warnings;
use Email::MIME;
use Data::Printer;
use feature qw/say/;

my $source = <<EOF;
Content-Type: multipart/related;
boundary="_004_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_";
type="multipart/alternative"
MIME-Version: 1.0

--_004_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_
Content-Type: multipart/alternative;
boundary="_000_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_"

--_000_47C8E15E8EEDCB4E94E891F9414C019A0CB5BDEE79DFW1MBX07mex0_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Test Body
EOF

my $msg = Email::MIME->new($source);

for my $part ($msg->parts) {
    if ($part->content_type =~ m!multipart/alternative!
            or $part->content_type eq '' )
        {
            say "Found Multipart"; 
            for my $subpart ($part->parts) {
                say $subpart->body;
            }
    }
}

输出:

C:\>perl test_mime.pl 
Found Multipart 
Test Body

0

您需要递归一层。 alternative 部分的 "body" 是一个 text/plain 部分,您需要检索并解析。

一般情况下,您不能假设任何特定结构,只能假定一个 multipart 由一个或多个单独的部分组成(它们本身可能是递归无限的 multiparts),通常您会想要遍历这些部分。

虽然 multipart/alternative 明确说明您应该选择其中一个成员部分(可能受平台功能和/或用户喜好的指导),但有时也会使用 multipart/mixedmultipart/related 达到相同的目的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接