[英]Decoding MIME email from Gmail API - \r\n and 3D - Python
[英]Failing to parse email from Gmail correcty because of `\r\n`
我在 Gmail 中有一封简单的电子邮件,如下所示:
Hi all
@alice - please prepare XXX for tomorrow
@bob - please prepare YYY for tomorrow
best,
Z
我想获取它,解析它并用换行符分割,所以我会得到一个包含 5 个元素的列表:
['Hi all','@alice ...', '@bob ...', 'best,','Z']
但由于某些原因在句子中我得到\r\n
这让我将行分成 2 行,尽管在原始电子邮件中没有新行。
我将其解析如下(在获得正确的凭据后)
txt = service.users().messages().get(userId=user.email, id=email_msg['id']).execute()
payload = txt["payload"]
headers = payload["headers"]
parts = payload.get("parts")[0]
data = parts["body"]["data"]
data = data.replace("-", "+").replace("_", "/")
decoded_message = str(base64.b64decode(data), "utf-8")
split = decoded_message.splitlines()
final_split = list(filter(None, split))
但随后我收到的消息如下所示:
Hi all\r\n\r\n@alice - please prepare XXX\r\nfor tomorrow\r\n@bob - please prepare YYY for tomorrow\\r\nr\nbest,\n\rZ
所以如果我按\r\n
或\n
拆分,我会得到无效的结果
当您使用b64decode()
解码数据时,您不会得到字符串,而是会得到一个字节字符串。 这是对差异的一个很好的解释。 在尝试解析消息之前,您必须将其转换为常规字符串。
您可以通过运行.decode("utf-8")
来做到这一点。 然后你可以使用.splitlines()
来分割消息。
txt = service.users().messages().get(userId=user.email, id=email_msg['id']).execute()
payload = txt["payload"]
headers = payload["headers"]
parts = payload.get("parts")[0]
data = parts["body"]["data"]
data = data.replace("-", "+").replace("_", "/")
decoded_data = base64.b64decode(data)
decoded_message = decoded_data.decode("utf-8") # decodes the byte string
split = decode_message.splitlines() # splits the message into a list
final_split = list(filter(None, split)) # this removes the blank lines
在消息上运行.decode()
将改变它:
Hi all\r\n\r\n@alice - please prepare XXX\r\nfor tomorrow\r\n@bob - please prepare YYY for tomorrow\\r\nr\nbest,\n\rZ
到原始消息:
Hi all
@alice - please prepare XXX for tomorrow
@bob - please prepare YYY for tomorrow
best,
Z
然后在.splitlines()
之后你会得到这个列表:
['Hi all', '', '@alice...', '@bob...', '', 'best,', 'Z']
请注意,有对应于空白行的空白字符串。 要摆脱它们,您可以运行最后一行final_split = list(filter(None, split))
,这将为您提供所需的内容。 还有其他方法:
['Hi all', '@alice...', '@bob...', 'best,', 'Z']
顺便说一句,我没有为此安装BeautifulSoup
,但如果你想使用它,你可能想在解码字节字符串后添加它。
正如 Daniel 在评论中所建议的,我使用 HTML 数据来正确提取消息:
我定义了HTML
解析器:
from html.parser import HTMLParser
from io import StringIO
def extract_text(html_text: str) -> str:
class MLStripper(HTMLParser):
def __init__(self):
super().__init__()
self.reset()
self.strict = False
self.convert_charrefs = True
self.text = StringIO()
def handle_data(self, d):
self.text.write(d)
def get_data(self):
return self.text.getvalue()
def strip_tags(html):
s = MLStripper()
s.feed(html)
return s.get_data()
cleaned_html_text = html_text.replace('</div>', '\n</div>').replace('\r\n', '')\
.replace('<br>', '\n').replace('\xa0', ' ')
return strip_tags(cleaned_html_text)```
然后在HTML
上运行它:
parts = payload.get("parts")[1] # take the HTML part
data = parts["body"]["data"]
data = data.replace("-", "+").replace("_", "/")
decoded_message = str(base64.b64decode(data), "utf-8")
extracted_message = extract_text(html_text=decoded_message)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.