You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GMail API邮件内容提取问题:HTML格式处理与纯文本获取

用Gmail API读取邮件时,含图片的邮件返回HTML格式,如何仅获取纯文本内容?

问题描述

我用Gmail API读取指定收件地址的收件箱邮件,目前遇到问题:纯文本邮件能直接获取内容,但带图片等非文本内容的邮件会以HTML页面形式存入变量。我要在「收件箱邮件」页面展示详情,想知道这种情况是否正常,能不能避免,以及如何只获取消息的文本内容。现有代码如下:

public async Task<List<Tuple<string, string, string, string, string, string>>> ReadEmails()
{
....
var emailListResponse = await emailListRequest.ExecuteAsync();
if (emailListResponse.Messages != null)
{
    foreach (var emailSummary in emailListResponse.Messages)
    {
        var emailInfo = await service.Users.Messages.Get("me", emailSummary.Id).ExecuteAsync();
        var emailSender = emailInfo.Payload.Headers.FirstOrDefault(h => h.Name == "From")?.Value;
        string emailAddress = emailSender.Contains("hello@info.mubi.com") ? "hello@info.mubi.com" :
              emailSender.Contains("contact@roonlabs.com") ? "contact@roonlabs.com" :
              "unknown";
        var emailSubject = emailInfo.Payload.Headers.FirstOrDefault(h => h.Name == "Subject")?.Value;
        var emailDate = emailInfo.Payload.Headers.FirstOrDefault(h => h.Name == "Date")?.Value;

        string emailBody = "";
        if (emailInfo.Payload.Parts == null && emailInfo.Payload.Body != null && !string.IsNullOrEmpty(emailInfo.Payload.Body.Data))
        {
            string base64EncodedBody = emailInfo.Payload.Body.Data;
            base64EncodedBody = base64EncodedBody.Replace("-", "+").Replace("_", "/");
            byte[] data = Convert.FromBase64String(base64EncodedBody);
            emailBody = Encoding.UTF8.GetString(data);
        }
        else if (emailInfo.Payload.Parts != null)
        {
            foreach (var part in emailInfo.Payload.Parts) //metin, html, ekler vs varsa çok parçalı olarak kontrol edilmesi gerekiyor
            {
                if (part.MimeType == "text/plain" && !string.IsNullOrEmpty(part.Body.Data))
                {
                    string base64EncodedBody = part.Body.Data;
                    base64EncodedBody = base64EncodedBody.Replace("-", "+").Replace("_", "/");
                    byte[] data = Convert.FromBase64String(base64EncodedBody);
                    emailBody = Encoding.UTF8.GetString(data);
                    break;
                }
            }
        }
        emailDetails.Add(Tuple.Create(emailInfo.Id, emailAddress, emailSender, emailSubject, emailBody, emailDate));
    }
}
return emailDetails;
}

情况说明

这种情况是正常的。大部分带富媒体(图片、复杂排版)的邮件采用多部分MIME格式发送,通常会包含text/plain(纯文本)和text/html(富文本)两个版本;但部分营销邮件或自定义邮件可能只提供HTML版本,不附带纯文本内容。

问题原因

你的代码逻辑存在漏洞:

  • 当邮件为单部分格式(Payload.Parts == null)时,直接读取Payload.Body.Data,但未校验该内容的MimeType——如果邮件本身只有HTML版本,这里读取到的就是HTML代码。
  • 当邮件为多部分格式时,仅查找text/plain部分,若找不到则emailBody为空,但你遇到的HTML存入情况,是触发了单部分邮件的读取逻辑。

解决方案

要确保只获取纯文本内容,需优化代码逻辑,优先校验内容的MIME类型:

修改后的代码示例

public async Task<List<Tuple<string, string, string, string, string, string>>> ReadEmails()
{
    var emailDetails = new List<Tuple<string, string, string, string, string, string>>();
    // ... 省略emailListRequest初始化代码
    var emailListResponse = await emailListRequest.ExecuteAsync();
    
    if (emailListResponse.Messages != null)
    {
        foreach (var emailSummary in emailListResponse.Messages)
        {
            var emailInfo = await service.Users.Messages.Get("me", emailSummary.Id).ExecuteAsync();
            var emailSender = emailInfo.Payload.Headers.FirstOrDefault(h => h.Name == "From")?.Value;
            string emailAddress = emailSender.Contains("hello@info.mubi.com") ? "hello@info.mubi.com" :
                  emailSender.Contains("contact@roonlabs.com") ? "contact@roonlabs.com" :
                  "unknown";
            var emailSubject = emailInfo.Payload.Headers.FirstOrDefault(h => h.Name == "Subject")?.Value;
            var emailDate = emailInfo.Payload.Headers.FirstOrDefault(h => h.Name == "Date")?.Value;

            string emailBody = "";
            // 优先处理多部分邮件,查找text/plain部分
            if (emailInfo.Payload.Parts != null)
            {
                foreach (var part in emailInfo.Payload.Parts)
                {
                    if (part.MimeType == "text/plain" && !string.IsNullOrEmpty(part.Body.Data))
                    {
                        string base64EncodedBody = part.Body.Data.Replace("-", "+").Replace("_", "/");
                        byte[] data = Convert.FromBase64String(base64EncodedBody);
                        emailBody = Encoding.UTF8.GetString(data);
                        break;
                    }
                }
            }
            // 多部分未找到纯文本时,检查单部分邮件的MIME类型
            else if (emailInfo.Payload.Body != null && !string.IsNullOrEmpty(emailInfo.Payload.Body.Data))
            {
                if (emailInfo.Payload.MimeType == "text/plain")
                {
                    string base64EncodedBody = emailInfo.Payload.Body.Data.Replace("-", "+").Replace("_", "/");
                    byte[] data = Convert.FromBase64String(base64EncodedBody);
                    emailBody = Encoding.UTF8.GetString(data);
                }
                // 可选:若需要将HTML转为纯文本,取消注释以下代码(需引用HtmlAgilityPack库)
                // else if (emailInfo.Payload.MimeType == "text/html")
                // {
                //     string base64EncodedBody = emailInfo.Payload.Body.Data.Replace("-", "+").Replace("_", "/");
                //     string htmlContent = Encoding.UTF8.GetString(Convert.FromBase64String(base64EncodedBody));
                //     emailBody = HtmlToPlainText(htmlContent);
                // }
            }
            emailDetails.Add(Tuple.Create(emailInfo.Id, emailAddress, emailSender, emailSubject, emailBody, emailDate));
        }
    }
    return emailDetails;
}

// 辅助方法:将HTML转为纯文本(需安装HtmlAgilityPack NuGet包)
private string HtmlToPlainText(string html)
{
    var doc = new HtmlAgilityPack.HtmlDocument();
    doc.LoadHtml(html);
    return doc.DocumentNode.InnerText.Trim();
}

额外说明

  • 如果邮件仅提供HTML版本,你可以选择:
    1. 不存储该邮件的内容(或标记为“无纯文本内容”);
    2. 使用HTML解析库(如HtmlAgilityPack)将HTML转为纯文本,但会丢失原有的格式排版信息。

内容的提问来源于stack exchange,提问作者JacksonT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:10:07