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版本,你可以选择:
- 不存储该邮件的内容(或标记为“无纯文本内容”);
- 使用HTML解析库(如
HtmlAgilityPack)将HTML转为纯文本,但会丢失原有的格式排版信息。
内容的提问来源于stack exchange,提问作者JacksonT
相关产品推荐
相关产品推荐

