如何从零开始创建电子邮件解析器

所以,你的老板刚刚让你解决困扰公司的“电子邮件难题”:每个早晨,大量自动化邮件需要人工录入数据,严重拖慢了团队效率并堵塞邮箱。

你聪明又高效,很快想到可以构建一个电子邮件解析系统。这是个好主意!不过,这个过程比写几段脚本要复杂一些。下面是创建电子邮件解析器并成功自动化电子邮件数据录入的六个步骤

在开始之前:什么是解析及其含义

在计算机科学中,解析是指根据一套规则将文本拆分为若干子部件。

一个电子邮件解析器,就是让计算机能够读取邮件并根据特定规则处理它们。理想情况下,系统会自动从邮件中提取相关数据,并将其输入你的后台应用程序。欢迎阅读这篇关于电子邮件解析深度解析的文章。

小小推荐:你了解 Parseur 吗?

自己开发一个电子邮件解析器很有趣,可以帮你深入理解底层原理。

但这个过程非常耗时。

注册您的免费账户
使用 Parseur 节省时间和精力。自动处理您的文档。

Parseur 完全从零开发始于2015年底,单单后端开发人员就投入了约5000小时,跨越六年时间,前端(包括所有用户界面和模板编辑器)也花费了数千小时。Parseur 背后的团队是拥有20年以上专业开发经验的资深工程师。

到现在为止开发还没有结束,甚至都无法估算打造一个“足够好”的文本解析器需要多少时间。

如果你需要快速见效,建议直接试用 Parseur。Parseur 是一款托管且易用的电子邮件解析器,能为你节省大量搭建自有方案的时间。快来了解Parseur 丰富强大的功能

1. 获取电子邮件

目前,这些邮件通常分散在员工个人邮箱、团队共享邮箱或公司总邮箱。

第一步应是设置一个邮箱账号来集中所有这些邮箱。甚至,如果你有勇气,还可以自建邮件服务器(即 SMTP 服务器)。

如果你懂这块内容,目前流行的 SMTP 服务器有:

  • Exim 是一款免费开源的邮件传输代理(也叫邮件服务器)。它是目前最流行的 SMTP 服务器,普及速度领先于排名第二的 Postfix。
  • Postfix 也是免费开源。它以“开箱即用、问题少”而著称。根据这篇邮件服务器市场份额文章,Exim 和 Postfix 共同占据了全球80%的邮件服务器份额。
  • 微软阵营则是无处不在的 Exchange。你可以通过 EWS 获取邮件,而不必使用 POP3IMAP。现在也可以让微软为你托管,当然是付费的。
  • 自己搭建。这个过程会比较漫长,但你能学到不少。最终你的服务器可能会更贴合你的需求,前提是你的需求不用考虑与海量邮件客户端兼容。如果你真的决定自己搭建,Python 标准库就有 smtpd 模块供你起步。

需注意的是,大量发送邮件而不被拉黑也是一门艺术,最好交给专业服务商。

同时,自己搭建邮件服务器的人越来越少。在云和 SaaS 时代,使用托管邮件服务更加方便省事。这个领域主要有以下几家:

  • Postmark 注重送达率和可靠性,而且也有免费套餐。
  • Mandrill 拥有先发优势,仍很受欢迎,主攻营销和事务类邮件。
  • Sendgrid 也定位为营销和事务型邮件平台。
  • Mailgun 更偏向开发者和 API 场景,同时有免费方案。

我们在 Parseur 特别喜欢 Postmark。他们的 API 很棒,文档也很出色,几乎所有主流语言都有 SDK 支持。

2. 将电子邮件转为标准数据格式

电子邮件是一种十分“上古”的格式,比《星球大战》还早,几十年下来积累了不少“弊病”。比如,最初标准没有考虑国际(非美式)字符支持。为了处理如 € 这样的特殊字符,需要参考三份重要的技术文档(即 RFC):

  • RFC 2047:支持邮件头中的国际字符(例如名字和主题)
  • RFC 5890:支持 DNS 中的国际化域名
  • RFC 6532:允许邮件头部分支持 UTF-8(另一种国际文本存储方式)

同样,这些如 Postmark、Mailgun 的服务商都能为你省去不少麻烦,帮你做好转换。关于 UTF-8、MIME、cp1252 等乱码困扰,你可以不用再头疼(你还没遇到?那你真的很幸运)。

比如 Mailgun,服务器会帮你接收邮件并转换为易于处理的 JSON 文档,自动处理好所有人知的 RFC 协议。随后会通过 webhook,将其以 HTTP POST 的形式推送到你指定的服务地址。

感兴趣可以看看所有与 SMTP 相关的 RFC 列表

例如,Mailgun 收到一封普通邮件后,会向你的服务器推送如下数据:

{
  "subject": "My favorite café",
  "sender": "John Doe <[email protected]>",
  "recipient": "Mr. Parseur <[email protected]>",
  "message": "It's called Awesome Café! See directions in the attachment. Bye.",
  "attachements": [
    { "name": "directions.pdf", "content": "https://url.with.content" },
    { "name": "cappucino.jpg", "content": "https://another.content.url" }
  ]
  /*... other interesting pieces of data here (read the doc, Luke) ...*/
}

是不是很直观?对比传统电子邮件格式就能感受到区别:

  MIME-Version: 1.0
  Received: by 102.29.23.176 with HTTP; Sat, 12 Aug 2016 14:13:31 -0700 (PDT)
  Date: Sat, 12 Aug 2016 14:13:31 -0700
  Delivered-To: =?ISO-8859-1?Q?Mr. Parseur <[email protected]>
  Message-ID: <CAAJL_=kPAJZ=fryb21wBOALp8-XOEL-h9j84s3SjpXYQjN3Z3A@mail.gmail.com>
  Subject: =?ISO-8859-1?Q?My=20Favorite=20Caf=E9
  From: =?ISO-8859-1?Q?John Doe <[email protected]>
  To: =?ISO-8859-1?Q?Mr. Parseur <[email protected]>
  Content-Type: multipart/mixed; boundary=mixed
  ==mixed
  Content-Type: multipart/alternative; boundary=alternative
  ==alternative
  Content-Type: text/plain; charset="utf-8"
  It's called Awesome Caf=C3=A9! See directions in the attachm= ent. Bye.
  ==alternative
  Content-Type: text/html; charset="utf-8"
  It's called <b>Awesome Caf=C3=A9</b>! See directions in the = attachment. Bye. ==alternative== ==mixed
  Content-Type: document/pdf; name="directions.pdf"
  Content-Disposition: attachment; filename="directions.pdf"
  Content-Transfer-Encoding: base64
  iVBORw [... the whole encoded attachment here ...] RK5CYII=
  ==mixed
  Content-Type: image/jpg; name="capuccino.jpg"
  Content-Disposition: attachment; filename="capuccino.jpg"
  Content-Transfer-Encoding: base64
  G+aHAAAA [... another attachment encoded here ...] ORK5CYII=
  ==mixed==

幸运的是,大多数主流编程语言都自带解析邮件的库,比如 Python 的 email 模块,或者 Ruby 的 RubyMail 库。

3. 数据入库

从这一步开始,你可以发挥你的编程能力,处理所有这些 HTTP 请求,并将数据妥善存入你选择的数据库中。

常用的语言和框架有:

如果你对具体格式没有特殊要求,相关代码会相对简单。不过你可能需要了解你的业务软件所支持的格式并作相应转化。常用的中间格式有 CSVJSON,但某些业务应用会用更偏门的二进制格式。

如果只是单纯地想存储数据(比如用于自有定制业务系统),那只需考虑数据的存储方式即可。

如果确定永远不会需要对这些存储邮件做统计分析或非顺序操作,你可以考虑用 MongoDB。但我也建议看看这篇精彩的博客后再做决定。

任何基于 SQL 的关系型数据库管理系统都能很好地存储邮件数据。至少要设计两张表:一张存储邮件,一张存储附件(如果要存的情况下)。

主流 SQL 数据库引擎如下,只要数据量和压力在单台服务器范围都可以胜任:

  • MySQL,以及其广受推荐、非官方分支 MariaDB,一直很流行。需要注意 Oracle 收购 MySQL 后支持力度不如以往。
  • Postgresql 属于功能更丰富、可扩展性更强的数据库,但配置维护也稍复杂。
  • 除了这些免费的开源数据库,还有像 Oracle 这样功能强大、适合大型企业的数据库。非常复杂且价格昂贵。你确定你的邮件系统需要这么大的扩展性吗?
  • 商业领域还有 Microsoft SQL server,近年来性能提升很大,如今也是 Oracle 的有力竞争对手。

到这里,如果你只是把邮件原封不动写入数据库,实际上基本已经开发完成了。

但为什么要止步于此呢?现在你手头正好拥有大量有价值的数据。这些都是紧贴你核心业务的数据。邮件内容中大概率包含发票、差旅、报价、潜在客户、正式客户等重要信息。

不如更进一步,从这些邮件中提取关键数据?完善数据细度能帮助你进一步自动化业务流程,极大节省你和员工的时间。

4. 从每封邮件中提取关键信息

这才是实际解析的关键所在。理想情况下我们希望这样做:

A screen capture of email parser overview
Schematics of an email parser transforming a received email into structured data (for example, a spreadsheet, or a database)

处理这个庞大问题有一些常见思路:

统计词频分析,或“关键词计数”

统计分析很适合没有固定模板的邮件,通常是人工撰写的邮件。你可以为每类邮件定义关键词组。然后分析每封邮件,分别统计各类关键词在邮件中出现的频次,然后判断邮件属于哪一类。

这种做法在情感分析等场景效果很好。例如,你可以设定“满意客户”和“愤怒客户”两类,把满意邮件发给老板,把愤怒邮件直接扔进垃圾箱(开玩笑啦,但你明白这个思路)。

不过你也清楚,人类之间交流容易出错、出现歧义,对语境极敏感。只要没有真正的人工智能,这些歧义就无法自动消解,很容易导致系统失灵甚至无法使用。

正则表达式

这种方法适用于自动生成的邮件——这类邮件大部分内容都保持不变。

比如解析美国航空公司的一百万封订票邮件,只抽取乘客姓名。你可以写一个正则表达式把整封邮件匹配,只捕获乘客姓名。乍一看很简单,但邮件其他部分变了怎么办?多个乘客又该怎么抓取?问题马上暴露了。

Python 有优秀的正则表达式库,Ruby 标准库也自带有 Regexp 模块,JavaScript 当然也内置了正则表达式对象

但是正则表达式非常难维护,可读性也堪忧。许多 Parseur 客户告诉我们,他们最初自己写了基于正则表达式的解析器,但面对每天新变动的邮件内容完全招架不住,维护耗时难以支撑下去。

5. 托管解析?Parseur 为你省事!

如果能直接拿到想要的数据,轻松填入 Excel 表格或数据库,是不是很爽?

这正是 Parseur 的目标。我们为你提供简单的“所见即所得”操作界面,让你只需标注想要的数据一次即可。之后再发来类似邮件,数据将自动被提取并填写进 Excel 表格中。

你无需自己从头写电子邮件解析器,也不用在后续维护或手动操作。只要首次操作几分钟,每封邮件就能自动成为 Excel 表格中的一行。

6. 集成到你的业务系统

当你把抽取的数据整齐收入 Excel 表格,接下来就只需将其导入你的业务系统即可。

各种自动化平台如 ZapierMake,也能极大帮助你——它们可以把你的电子邮件与业务应用连接起来。你只需简单编写一个连接器,就可以畅享其强大生态里的各种集成组件。

Parseur 支持对接 Google Sheets、Zapier、Integromat(现为 Make)、Microsoft Power Automate 等平台,仅需几步点击,就能让你的解析数据联通数千种应用。

祝你好运!

最后更新于

基于AI的数据提取软件。
立即开始使用Parseur。

自动提取电子邮件、PDF和电子表格中的文本。
节省数百小时的手动工作。
体验AI赋能的工作自动化。

Parseur rated 5/5 on Capterra
Parseur.com has the highest adoption on G2
Parseur rated 5/5 on GetApp
Parseur rated 4.5/5 on Trustpilot