如何解析电子邮件签名以单独获取详细信息?

时间:2015-08-03 07:52:31

标签: javascript regex email parsing signature

我要求我的项目解析我到达我的Gmail帐户的邮件签名。从签名我必须获取名字,姓氏,邮件ID等[只有发件人]。你能告诉我从哪里开始吗? ("从哪个地方开始"从某种意义上来说,这已经存在了吗?)

我已经完成了这个question,这个问题谈到删除签名的东西,但这与我的要求完全相反。对此的答案并没有解决我的问题。

我知道我可以使用正则表达式完成这项工作。但我也不想错过那些不遵循邮件签名礼节的邮件,比如删除" - "在签名之前,尾随连字符。

如果可能的话,请告诉我任何确切提供此功能的开源JavaScript项目。

提前致谢。

更新:我要查找的签名通常与业务相关,因此它们包含HTML内容或有时直接包含VCards。

更新:我只需要删除签名的每一行,并从这些行中获取详细信息。

4 个答案:

答案 0 :(得分:4)

回答这个问题有几个潜在的部分。

gmail界面中的签名

在gmail界面中,签名相当容易抓取。它们包含在<font color="#888888">中,因此如果您从gmail界面获取签名,那么使用xmlreader获取这些内容应该非常简单。这不会得到gmail没有检测到的任何签名。

使用签名设置从gmail发送的邮件中的签名

只需在电子邮件的html版本中查找<div class=3D"gmail_signature">即可。

签名解析的一般方法

我随意将目标限制为发件人的联系信息。因此,在签名中仅获取联系信息是最有意义的。由于许多电子邮件包含发件人以外的人的联系信息,因此第一步是隔离签名。

一旦签名被隔离,每行可以与正则表达式模式匹配。我绝不是一个正则表达式专家,所以我不会试图在这里描述实际的模式。

以下是方法,而不是代码。实际的实现应该非常简单。

从电子邮件中抓取签名

  1. 删除目标邮件中除呈现文本之外的所有内容。将\ n换行留在适当的位置。
  2. 从消息的底部开始工作,将每一行存储在变量中。当你排长队时停止(60多个字符,确切的数字需要实验 1 )。不要包括长线。
  3. 如果某个地方中间有多个\ n,请删除它们以及它们上方的所有内容。这是为了消除任何短线和大多数结束致敬。 2
  4. 现在签名被隔离了。

    以下是对剩余部分的一些假设。除非指定了订单,否则假设它们可以按任何顺序排列。

    A) End of message and closing greeting will be the topmost line(s)
    B) Name
    C) Phone Number
    D) Email Address
    E) Mailing Address
    F) Tag line or witty saying, etc.
    

    1 60个字符的行长度是基于RFC 2822强烈暗示行应该是78个字符长的事实。 Gmail尊重这一点。除非整个地址写成一行,否则大多数签名行都会短于此。使用此方法无法正确检测极短电子邮件(&lt; 20字)的签名,但首先检查邮件总长度并使用不同的代码来处理该邮件是非常简单的。

    2 由于大多数签名都是自动添加的,因此通常会有一系列换行符。但是,手工签名可能不符合此模式,因此根据您正在处理的电子邮件类型,您可能会发现此步骤无益或有害。

    识别签名的部分

    现在您已经减少了正则表达式的误报匹配的可能性,您可以看到剩余的行是否与您的任何模式匹配。

    1. 用换行符替换公共分隔符,|是一个常见的例子。
    2. 检查是否有任何行符合您的正则表达式模式。如果他们这样做,将其从进一步的考虑中删除最难的部分是将名称与其他东西区分开来。建议的顺序:

      电子邮件

      电话

      邮政编码(如果找到邮政编码,则为地址)

    3. 左边应该是关闭的称呼,名称,标记行以及上面项目的任何格式错误的部分。请注意,虽然大多数正则表达式用于查找错误(用于验证),但您希望匹配错误,从进一步处理中删除行,然后验证或规范化。

      在我看来,弄清楚哪个部分区别于标记线的最难的部分。以下是一些有助于解决常见案例的建议:

      1. 名称由少量词组成。
      2. 名称包含某些地方的句点 - 在1-3个字母后面。 (法语有M. for Messieur)
      3. 名称不包含太多标点符号。除了上面的时期之外,可能只有短划线和撇号。您可能会在标题之前遇到逗号问题,例如,John Lawyer,Esq。
      4. 标记行可能以逗号结尾
      5. 大写可以提示(但不能明确说明)是否有名称。
      6. 此外,您可以将常见的结束致敬词(真诚地,感谢,欢呼等)列入黑名单。如果将其缩小为一行或两行,则较高的一行很可能是名称,而较低的一行最有可能标记行。

        有关识别名称的详细信息,请参阅Find names with Regular Expression。请记住,虽然在一般情况下编写解决方案应该很容易,但自然语言处理是巨大的,超出了像我这样的凡人的范围。 Named Entity Recognition is a known challenge。希望,我所描述的内容在大多数情况下都能为您提供帮助。

答案 1 :(得分:1)

我不使用GMail,所以我实际上是根据我所拥有的包含签名的GMail消息构建了这个答案。这是垃圾邮件。不过,让我们看看这会让你有多远......

var sig = document.querySelector('div[data-tooltip="Show trimmed content"]')
                  .parentNode.nextElementSibling

这应该将一个名为sig的新变量设置为紧跟隐藏/显示点之后的内容。请注意,它还会找到引用的对话。这是一个开始,而不是一个完整的解决方案。

Element.querySelector()是一种通过CSS搜索元素的便捷方式。在这种情况下,我寻找工具提示。我们想要的元素实际上是一个级别,然后是下一个元素(CSS不能做但JS可以做的事情。)

答案 2 :(得分:1)

我想这个解决方案不仅仅是几行代码。我认为它需要某种专门用于此的特殊处理,例如签名解析器或NLP。这个问题从八月开始,我想现在是时候关闭它了。

答案 3 :(得分:0)

有一个API可以解析签名中的联系人数据。它还将处理回复链。请参阅下面的示例。

https://www.sigparser.com

您可以在https://api.sigparser.com上的招摇细节页面上测试API。

(我是SigParser.com btw的创造者)

以下是一个示例回复:

{
    "error": null,
    "contacts": [
        {
            "firstName": "Bill",
            "lastName": "Gates",
            "emailAddress": "bgates@example.com",
            "phoneNumber": null,
            "fax": null,
            "address": null,
            "title": null,
            "phoneNumbers": [
                {
                    "rationalType": null,
                    "type": "Mobile",
                    "phoneNumber": "7774448888"
                }
            ],
            "twitterUrl": [
                {
                    "emailAddress": "bgates@example.com",
                    "url": "https://twitter.com/BillGates"
                }
            ],
            "linkedInUrl": [
                {
                    "emailAddress": "bgates@example.com",
                    "url": "https://www.linkedin.com/in/williamhgates/"
                }
            ]
        }
    ],
    "isSpammyLookingEmailMessage": false,
    "isSpammyLookingSender": false,
    "isSpam": false,
    "from_LastName": "Gates",
    "from_FirstName": "Bill",
    "from_Fax": null,
    "from_Phone": null,
    "from_Address": null,
    "from_Title": null,
    "from_MobilePhone": "7774448888",
    "from_OfficePhone": null,
    "from_LinkedInUrl": "https://www.linkedin.com/in/williamhgates/",
    "from_TwitterUrl": "https://twitter.com/BillGates",
    "from_EmailAddress": "bgates@example.com",
    "emails": [
        {
            "from_EmailAddress": "bgates@example.com",
            "from_Name": "Bill Gates",
            "textBody": "Hi, good seeing you the other day.\r\n--\r\nBill Gates\r\nCell 777-444-8888LinkedInTwitter",
            "htmlLines": [
                "<div>Hi, good seeing you the other day.</div>",
                "<div>--</div>",
                "<div>Bill Gates</div>",
                "<div>Cell 777-444-8888</div><a href=\"https://www.linkedin.com/in/williamhgates/\">LinkedIn</a><a href=\"https://twitter.com/BillGates\">Twitter</a>"
            ],
            "date": "2017-01-01T00:00:00",
            "didParseCorrectly": true,
            "to": [],
            "cc": []
        }
    ]
}