首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Perl使用MIME::Parser解析没有部分的电子邮件正文

Perl使用MIME::Parser解析没有部分的电子邮件正文
EN

Stack Overflow用户
提问于 2019-06-06 02:43:09
回答 1查看 852关注 0票数 0

我有一个perl脚本,它使用MIME::Email来解析从stdin收到的电子邮件,但它不能处理没有部分的电子邮件。我没有能力在发送电子邮件之前修改它们。

我希望能够识别电子邮件的重要部分,无论它是HTML还是文本,并将其存储在缓冲区中以便稍后处理。这些电子邮件中的许多都来自以某种方式自动生成的邮件列表。

有时,它们似乎只有一个没有边界的"Content-Type:“头。

代码语言:javascript
复制
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

其他时候,它们有多个文本/普通部分,其中一个是电子邮件的正文,另一个是签名。

在这之后还有一些其他的标题行,但是正文只显示没有任何边界标记。

这是我两年前的帖子,展示了我是如何最终弄清楚如何使用parts Parsing email with Email::MIME and multipart/mixed with subparts解析大多数电子邮件的

代码语言:javascript
复制
use strict;
use MIME::Parser;
use MIME::Entity;
use Email::MIME;
use Email::Simple;
my $parser = MIME::Parser->new;
$parser->extract_uuencode(1);
$parser->extract_nested_messages(1);
$parser->output_to_core(1);
my $buf;
while(<STDIN> ){
        $buf .= $_; 
}

my $entity = $parser->parse_data($buf);

$entity->dump_skeleton;
my $num_parts = $entity->parts;
for (my $i=0; $i < $num_parts; $i++) {
    my $part = $entity->parts($i);
    my $content_type = $part->mime_type;
    my $body = $part->as_string;

    print "body: $body\n";
}

永远不会打印正文文本。仅来自dump_skeleton的以下内容:

代码语言:javascript
复制
Content-type: text/plain
Effective-type: text/plain
Body-file: NONE
Subject: Security update 

我真的希望能够修改我现有的脚本(在之前的stackexchange帖子中显示),以便能够打印这样的电子邮件,而不会有任何边界。

这是不是很差的格式?我找不到任何可以用来可靠地打印电子邮件正文、主题和其他基本标题的库的示例,而没有复杂的步骤来逐个分析整个邮件。

我知道mimeexplode可以做到,但我不知道怎么做到。我需要将邮件正文存储在缓冲区中以进行操作,因此使用像mimeexplode这样的命令行程序也是一种间接的方式。

EN

回答 1

Stack Overflow用户

发布于 2019-06-06 03:16:17

这对我来说并不完全清楚你试图实现什么,因为你只发布代码,而不是足够详细的背后的意图。但是您正在使用parts检查消息,该消息是返回multipart/*或类似部分(即message/rfc822)的clearly documented,并且不处理单个消息:

...返回所有子部分的数组,如果没有(例如,如果这是单部分消息或退化的多部分),则返回空数组。在标量上下文中,这将返回部件的数量。

如果您只想获取所有部分,包括独立的“部分”(即,不属于任何内容的单个实体),只需使用parts_DFS,如下例所示,它将打印具有非零正文的所有实体的正文:

代码语言:javascript
复制
use MIME::Parser;
my $parser = MIME::Parser->new;
my $entity = $parser->parse(\*STDIN);
for my $part ($entity->parts_DFS) {
    defined(my $body = $part->bodyhandle) or next; # has no body, likely multipart or similar
    print "body: ".$body->as_string."\n";
}

编辑:考虑到你已经更新了问题,你不是在寻找所有部分,而是在寻找正文部分。确定实际的主要部分并不容易,但您可以尝试使用第一个text/*部分,它是内联的。这可能看起来像这样:

代码语言:javascript
复制
use MIME::Parser;
my $parser = MIME::Parser->new;
my $entity = $parser->parse(\*STDIN);
for my $part ($entity->parts_DFS) {
    defined(my $body = $part->bodyhandle) or next; # has no body, likely multipart or similar
    if (my $disp = $part->head->get('content-disposition')) {
        next if $disp !~ m{inline}i;
    }
    print "body: ".$body->as_string."\n";
    last;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56466303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档