Net::IMAP::Simple 没有收到完整的消息
Net::IMAP::Simple get not getting the entire message
我不太懂 perl,所以也许我做了一些蠢事。
我的问题是我目前正在使用脚本通过 IMAP 协议获取电子邮箱中包含的所有消息,在 PERL 中使用 Net::IMAP::Simple,但它没有给我完整的消息正文。
我的整个代码如下所示:
use strict;
use Net::IMAP::Simple;
my $imap = Net::IMAP::Simple->new('xxxxxxxxxxxxxx') or die 'Impossible to connect '.$!;
$imap->login('xxxxxxxx', 'xxxxxxxxx') or die 'Login Error!';
my $nbmsg = $imap->select('INBOX') or die 'Impossible to reach this folder !';
print 'You have '.$nbmsg." messages in this folder !\n\n";
my $index = $imap->list() or die 'Impossible to list these messages !';
foreach my $msgnum (keys %$index) {
#if(!$imap->seen($msgnum)) {
my $msg = $imap->get($msgnum) or die 'Impossible to retrieve this message'.$msgnum.' !';
print $msg."\n\n";
# }
}
$imap->quit() or die 'quitting issue !';
每次它检索电子邮件时,它都会给我第一个字符(在我的例子中是发送消息的机器人生成的密码无用元数据),而不是整个正文。
编辑:这是输出中显示的正文部分:
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: BASE64
Q2UgbWVzc2FnZSBhIMOpdMOpIGfDqW7DqXLDqSBhdXRvbWF0aXF1ZW1lbnQgcGFyIGwnaW1wcmlt
YW50ZSBtdWx0aWZvbmN0aW9ucyBYZXJveCBYRVJPWF83ODMwLgogICBFbXBsYWNlbWVudCBkdSBz
eXN0w6htZSA6IAogICBBZHJlc3NlIElQIHN5c3TDqG1lIDogMTkyLjE2OC4xLjIwMAogICBBZHJl
c3NlIE1BQyBzeXN0w6htZSA6IDlDOjkzOjRFOjMzOjM1OkJECiAgIE1vZMOobGUgc3lzdMOobWUg
OiBYZXJveCBXb3JrQ2VudHJlIDc4MzAKICAgTnVtw6lybyBkZSBzw6lyaWUgc3lzdMOobWUgOiAz
OTEyNzk4ODk0CgpMJ0Fzc2lzdGFudCBkZSBjb21wdGV1ciBhIGVudm95w6kgbGUgcmVsZXbDqSBz
dWl2YW50IGF1IHNlcnZldXIgZGUgY29tbXVuaWNhdGlvbiBYZXJveCBTTWFydCBlU29sdXRpb25z
IGxlICAxNC8xMS8xNiAgIDA5OjI0OiAKICBUaXJhZ2VzIGVuIG5vaXIgOiAxMzIwNwogIFRpcmFn
ZXMgZW4gY291bGV1ciA6IDkyNjg3CiAgVG91cyBsZXMgdGlyYWdlcyA6IDEwNTg5NA==
它总是以这个“==”结尾,顺便说一句,这让我觉得模块正在缩短输出。
我在 CPAN 文档中查看了有关它的一些细节,但遗憾的是没有找到任何东西。
您的消息被编码为 Base64. It's perfectly normal for emails to have that MIME type, though not required. You need to decode them. A good way to do that is to use MIME::Base64。请注意 ==
是 Base64 字符串的一部分。这是使字符串具有正确长度的填充。
use strict;
use warnings;
use MIME::Base64 'decode_base64';
my $decoded_msg = decode_base64($msg_body);
但是,您需要从这些消息 object 中获取 body。文档对此含糊不清,它没有说明那些 object 是什么,并且 get
仅 returns 原始消息。
我建议您安装 Data::Printer 并用它来转储您的 $msg
object 之一。该转储将包括 object 的内部结构(可能是哈希引用),以及 object 具有的所有方法。 object 可能包含一个访问器来获取已解码的内容。如果是这样的话,你不需要自己解码。如果不是,请将 body 取出并使用 decode_base64
.
对其进行解码
更新:我阅读了 the code, and it creates Net::IMAP::Simple::_message objects in the get
method. There is a package definition at the top of the code。这有点复杂,但很明显。 object后面的数据结构是用lines的arrayref,所以我上面说错了。
q( package Net::IMAP::Simple::_message;
use overload fallback=>1, '""' => sub { local $"=""; "@{$_[0]}" };
sub new { bless $_[1] })
再往下:
return wantarray ? @lines : Net::IMAP::Simple::_message->new(\@lines)
所以要获得 body,您需要去掉 header 字符串。转储 object 后,您应该会看到数组开头有多少个元素是 header 和空行。我假设索引 0
是 header 行,索引 1
是空行。如果你不在乎这些,你可以把它们扔掉。
这将改变 object。
shift @$msg; # get rid of header
shift @$msg; # get rid of empty line
my $decoded_msg = decode_base64("$msg");
我不太懂 perl,所以也许我做了一些蠢事。 我的问题是我目前正在使用脚本通过 IMAP 协议获取电子邮箱中包含的所有消息,在 PERL 中使用 Net::IMAP::Simple,但它没有给我完整的消息正文。 我的整个代码如下所示:
use strict;
use Net::IMAP::Simple;
my $imap = Net::IMAP::Simple->new('xxxxxxxxxxxxxx') or die 'Impossible to connect '.$!;
$imap->login('xxxxxxxx', 'xxxxxxxxx') or die 'Login Error!';
my $nbmsg = $imap->select('INBOX') or die 'Impossible to reach this folder !';
print 'You have '.$nbmsg." messages in this folder !\n\n";
my $index = $imap->list() or die 'Impossible to list these messages !';
foreach my $msgnum (keys %$index) {
#if(!$imap->seen($msgnum)) {
my $msg = $imap->get($msgnum) or die 'Impossible to retrieve this message'.$msgnum.' !';
print $msg."\n\n";
# }
}
$imap->quit() or die 'quitting issue !';
每次它检索电子邮件时,它都会给我第一个字符(在我的例子中是发送消息的机器人生成的密码无用元数据),而不是整个正文。
编辑:这是输出中显示的正文部分:
Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: BASE64
Q2UgbWVzc2FnZSBhIMOpdMOpIGfDqW7DqXLDqSBhdXRvbWF0aXF1ZW1lbnQgcGFyIGwnaW1wcmlt YW50ZSBtdWx0aWZvbmN0aW9ucyBYZXJveCBYRVJPWF83ODMwLgogICBFbXBsYWNlbWVudCBkdSBz eXN0w6htZSA6IAogICBBZHJlc3NlIElQIHN5c3TDqG1lIDogMTkyLjE2OC4xLjIwMAogICBBZHJl c3NlIE1BQyBzeXN0w6htZSA6IDlDOjkzOjRFOjMzOjM1OkJECiAgIE1vZMOobGUgc3lzdMOobWUg OiBYZXJveCBXb3JrQ2VudHJlIDc4MzAKICAgTnVtw6lybyBkZSBzw6lyaWUgc3lzdMOobWUgOiAz OTEyNzk4ODk0CgpMJ0Fzc2lzdGFudCBkZSBjb21wdGV1ciBhIGVudm95w6kgbGUgcmVsZXbDqSBz dWl2YW50IGF1IHNlcnZldXIgZGUgY29tbXVuaWNhdGlvbiBYZXJveCBTTWFydCBlU29sdXRpb25z IGxlICAxNC8xMS8xNiAgIDA5OjI0OiAKICBUaXJhZ2VzIGVuIG5vaXIgOiAxMzIwNwogIFRpcmFn ZXMgZW4gY291bGV1ciA6IDkyNjg3CiAgVG91cyBsZXMgdGlyYWdlcyA6IDEwNTg5NA==
它总是以这个“==”结尾,顺便说一句,这让我觉得模块正在缩短输出。
我在 CPAN 文档中查看了有关它的一些细节,但遗憾的是没有找到任何东西。
您的消息被编码为 Base64. It's perfectly normal for emails to have that MIME type, though not required. You need to decode them. A good way to do that is to use MIME::Base64。请注意 ==
是 Base64 字符串的一部分。这是使字符串具有正确长度的填充。
use strict;
use warnings;
use MIME::Base64 'decode_base64';
my $decoded_msg = decode_base64($msg_body);
但是,您需要从这些消息 object 中获取 body。文档对此含糊不清,它没有说明那些 object 是什么,并且 get
仅 returns 原始消息。
我建议您安装 Data::Printer 并用它来转储您的 $msg
object 之一。该转储将包括 object 的内部结构(可能是哈希引用),以及 object 具有的所有方法。 object 可能包含一个访问器来获取已解码的内容。如果是这样的话,你不需要自己解码。如果不是,请将 body 取出并使用 decode_base64
.
更新:我阅读了 the code, and it creates Net::IMAP::Simple::_message objects in the get
method. There is a package definition at the top of the code。这有点复杂,但很明显。 object后面的数据结构是用lines的arrayref,所以我上面说错了。
q( package Net::IMAP::Simple::_message; use overload fallback=>1, '""' => sub { local $"=""; "@{$_[0]}" }; sub new { bless $_[1] })
再往下:
return wantarray ? @lines : Net::IMAP::Simple::_message->new(\@lines)
所以要获得 body,您需要去掉 header 字符串。转储 object 后,您应该会看到数组开头有多少个元素是 header 和空行。我假设索引 0
是 header 行,索引 1
是空行。如果你不在乎这些,你可以把它们扔掉。
这将改变 object。
shift @$msg; # get rid of header
shift @$msg; # get rid of empty line
my $decoded_msg = decode_base64("$msg");