使用IMAPClient读取邮件HTML表格时出现随机=号插入错误如何解决?
问题原因与解决方案
问题根源
- 你获取的原始邮件正文未做
Quoted-Printable传输编码解码,随机插入的=字符、异常<==/td>类标签都是该编码未解码的典型特征,IMAPClient默认返回原始传输字节流,不会自动完成编码转换。 - 你使用
BODY[TEXT]获取邮件正文,HTML邮件的完整表格内容存储在BODY[HTML]部分,BODY[TEXT]是邮件服务商自动转换的纯文本降级版本,本身HTML结构就存在缺失。 - 原有代码中如果匹配到多封邮件,
body变量只会保留最后一封邮件的内容,会丢失前面邮件的处理结果。
修正代码
import quopri from imapclient import IMAPClient from bs4 import BeautifulSoup import pandas as pd HOST = 'imap.gmail.com' USERNAME = username PASSWORD = password ssl = True server = IMAPClient(HOST, use_uid=True, ssl=ssl) server.login(USERNAME, PASSWORD) select_info = server.select_folder('INBOX') messages = server.search(['FROM', sender_address]) # 存储所有匹配邮件提取出的表格 df_list = [] if len(messages) > 0: # 将BODY[TEXT]替换为BODY[HTML]获取标准HTML正文 for mail_id, data in server.fetch(messages,['ENVELOPE','BODY[HTML]']).items(): envelope = data[b'ENVELOPE'] raw_body = data[b'BODY[HTML]'] # 第一步:解码Quoted-Printable编码 decoded_qp = quopri.decodestring(raw_body) # 第二步:转换为字符串,可根据实际邮件编码替换utf-8为gbk等 body = decoded_qp.decode('utf-8', errors='ignore') # 单封邮件单独解析 soup = BeautifulSoup(body, 'html.parser') tables = soup.find_all('table') if tables: # 提取第一个表格,可根据需求调整索引 df = pd.read_html(str(tables))[0] df_list.append(df) # 后续可直接使用df_list,或合并所有表格 if df_list: final_df = pd.concat(df_list, ignore_index=True)
补充注意点
- 如果解码后仍存在乱码,可以从邮件的
Content-Type头中读取实际编码,替换代码中的utf-8即可 - 若邮件是多部分嵌套结构(包含附件、富文本、HTML等多个分段),建议搭配Python内置的
email库解析完整邮件结构,兼容性比直接获取BODY[HTML]更好
内容的提问来源于stack exchange,提问作者younggotti
相关产品推荐
相关产品推荐

