mbox:Unix 的入门级邮箱

虽然老套却很好用

本章介绍一些基本的邮件(虽然社交网络有很多优点,但是在未来的几年中,邮件仍将是互联网的主打产品)分析工具和技术,以回答以下问题:

谁发送的邮件最多?

一天中是否存在某个特定的时间(或是一周中的某天),这时候发件人最可能收到对一个问题的回复?

几个人之间,谁发送的消息最多?

讨论最热烈的话题是什么?

虽然社交媒体网站积累了越来越多的准实时社交数据,但它还是存在重大的缺点。和Email 不同,社交网络数据是由服务提供者集中管理的,服务提供者可以创建规则,规定访问它的方式,以及你能做什么、不能做什么注1。另一方面,邮件数据主要是分 散管理的,它以富邮件列表的形式分散在Web 上,是对一连串有趣话题的讨论。如果你使用Google 和Yahoo! 这类服务提供商提供的服务来检索邮件列表,它们就会限制邮件列表数据的使用,但可以用稍微简单的方法来挖掘内容,这会提高成功率:可以通过订阅列

趋势。

注1:

你可能已经猜到了,要想找到作为例证的真实的社交数据集并不容易(如果还能找到的话),但幸运的是,本章有最为真实的数据集:公开的Enron 邮件数据集(http://www. cs.cmu.edu/~enron/ )。

mbox:Unix 的入门级邮箱(1)

假如你之前还没有见过mbox 文件,那么我可以告诉你,从根本上说它是大型的串联邮件消息文本,很容易由基于文本的工具获取。每封邮件的开头都是由特殊的From_line 标记的,并将它格式化为"From [email protected] Fri Dec 25 00:06:42 2009" 模式,其中日期/时间戳是asctime(http://opengroup.org/onlinepubs/007908775/xsh/asctime.html )格式,它是一种标准的固定长度的时间戳表示。

注意:mbox 格式是很常见的,大多数邮件客户端都提供了“导出”或者“另存为”选项,可以将数据导出为此格式,而不关心底层实现。

在mobox 文件中,两封邮件之间的边界是由两个新行前面的(除了第一次出现)From_ line 决定的。示例3-1 是一个虚构的mbox 的一小部分,它包含两条消息。

示例3-1 :示例mbox 文件的一小部分

mbox:Unix 的入门级邮箱 
mbox:Unix 的入门级邮箱 

但是可以证明mbox 中至少还存在另一封邮件,在示例3-1 中,我们可以看到两封邮件。按时间先后来说,第一封邮件是由Buddy 撰写的,发送给[email protected]. org ,告诉他玩具已经装好了。mbox 中的另一封邮件是Santa 对Rudolph 的回复。示例mbox 中没有显示的是一封中间邮件,Rudolph 给Santa 转发了Buddy 的邮件,解释了他迟到的原因。虽然我们可以通过阅读这些邮件文本推断出发生的事情,但是我们也可以从Message-ID 、References 和In-Reply-To 标头中得到重要线索。这些标头非常直观,为显示线程化讨论和那类事情的算法提供了基础。稍后我们会研究在“电子邮件线程化”中使用了这些字段的一个著名算 法,但是重点是每封邮件都有唯一的邮件ID ,包含了对这封正在被回复的确切邮件是一个回复的情况的引用,而且可以在答复链中引用多封其他邮件,它们是正在进行的讨论进程的一部分。

注意:除了使用一些Python 模块来干这些没有技术含量的活之外,我们不会讨论电子邮件消息的相关细节,如多部分邮件、MIME(http://en.wikipedia.org/wiki/MIME )、7位内容传输编码等。如果你想仔细研究一下的话,毫不费力就能找到全面涵盖这些主题的极好的参考资料。

这些标头极为重要。即使是在这个简单的示例中,你也可以看到当你在解析一封邮件的正文时,事情如何变得混乱:Rudolph 的客户端使用“>”符号引用转发的内容,而Santa 的邮件客户端过去常常直接回复,没有引用任何内容,但是使用了一个人类可读的邮件标头。即使不是完全没有可能,但尝试从mailbox 数据中解析出确切的对话流仍很困难,因为所包含的二义性使它成为可能。当你想查看这些信息时,如果你感兴趣的是比研究原始数据存储更方便的技术的话,大多 数邮件客户端都能够显示比你平常看到的更多的扩展邮件标头。示例3-2 说明了示例3-1 的邮件流,图3-1 显示了Apple Mail 的示例标头。

mbox:Unix 的入门级邮箱 
(点击查看大图)图3-1 :大多数邮件客户端都允许通过一个选项菜单来查看扩展标头

示例3-2 :示例3-1 的消息流

 

幸运的是,有很多可以做的,而你不必从根本上重新实现一个邮件客户端。而且,如果

你只是想要浏览邮箱,可以简单地将它导入到邮件客户端并浏览它,对吧!虽然只是固定的套路,但也值得花一点时间来研究你的邮件客户端是否有一个“以mbox 格式导入/ 导出数据”的选项,这样你才可以使用本章的工具来对它进行交叉分析。

Python 提供了一些解析mbox 数据的基本工具,示例3-3 的脚本介绍了一种将mbox 数据转换为一系列JSON 对象的基本方法。

警告:请注意,示例3-3 的好几个地方包含了decode('utf-8', 'ignore') 函数。当使用email 或网页这些基于文本的数据时,由于特别的字符编码,很容易会遇到臭名昭著的UnicodeDecodeError ,发生了什么或者如何解决这个问题通常并不明显。简略的回答是可以在任何字符串值中运行decode() 函数,并且把它传递给第二个参数,该参数指定了在碰到UnicodeDecodeError 时应该怎么办。默认值是'strict' ,它会引发异常,但是也可以根据需要使用'ignore' 或'replace' 来代替它。

示例3-3 :将mbox 转换为更为方便的JSON 结构(mailboxes_jsonify_mbox.py)

mbox:Unix 的入门级邮箱 
mbox:Unix 的入门级邮箱

警告:从Python 2.6.x 开始,jsonlib2 (可以通过easy_install 获得)这类基于C语言的第三方模块要比标准库模块快得多,但是Python 2.7 附带了与jsonlib2 这类模块等同的更新(http:// bugs.python.org/issue4136 )。为了便于说明,就不多介绍在相当大的JSON 结构(大约为100MB )使用标准库和jsonlib2 之间的区别了。

这段脚本解析出了Email 中最相关的信息,并构建出了可移植的JSON 对象。我们能做的还有很多,但是它解决了最常见的问题,包括解码quoted-printable(QP )文本(http:// en.wikipedia.org/wiki/Quoted-printable )和去除HTML 标签的简单机制。quopri 模块用于解决QP 格式,它是一种用于将8位内容转换为7位通道的编码注2。示例3-3 的简略的示例输出如示例3-4 所示。

示例3-4 :来自示例3-1 的示例mbox ,由示例3-3 产生的示例JSON 输出

 
mbox:Unix 的入门级邮箱 
既然使用了新发现的技术将邮件数据解析为可访问的格式,迫切想要开始分析它就是很自然的事情了。本章 剩余的部分将使用公开的Enron 邮件数据作为mbox 下载。enron. mbox.gz 文件是一个mbox ,它是由来自原始Enron 语料库中的、出现在“inbox ”文件夹中的消息构造的,而enron.mbox.json.gz 文件使用示例3-3 的脚本将相同的数据转成JSON 。虽然没有作为一个示例在这里显示,但是可以下载这段脚本,它使用mailboxes_ convert_enron_inbox_to_mbox.py 脚本( http://github.com/ptwobrussell/Mining-the-Social-Web/blob/master/python_code/mailboxes__convert_enron_inbox_to_mbox.py )将原始Enron 数据转换为mbox 格式。请注意,如果你在线搜索,你可能会在 http://www.cs.cmu. edu/~enron/ 上得到最接近Enron 数据的数据,它是一种非标准的格式,更适合研究,包括日历信息、笔记等。用于将数据集的一部分转换为显式标记为mbox 格式的“Inbox 数据”的脚本,可以从 http://github.com/ptwobrussell/Mining-the-Social-Web/blob/master/ python_code/mailboxes__convert_enron_inbox_to_mbox.py 上获得。本章剩余的部分假设你使用的是可以下载的mbox 数据。

你可能感兴趣的:(unix)