python获取邮件并转为pdf

业务场景

客户要求写一个程序能够自动登录他的邮箱,然后读取邮件中的求职者简历,并将该类型的邮件转为pdf以及获取关键信息和附件。

实现方式

1、使用imaplib库访问医院HR邮箱,获取邮件并使用email将邮件信息解析为html信息
2、筛选出简历信息后使用pdfkit将邮件内容转为pdf
3、使用etree读取html并通过find找寻关键信息存
主要逻辑:
1、业务方法resume_collect调用getMail获取邮件list进行解析
2、获取邮件方法getMail使用imaplib登录邮箱获取邮件信息通过解析邮件首部方法parseHeader、解析邮件/信体方法parseBody将邮件元数据转为易解析的html和text信息
3、解析邮件首部方法parseHeader通过email库解析邮件的主题、发件人、收件人等首部信息
4、解析邮件/信体方法parseBody通过email库解析邮件的信体以及附件内容

获取邮件getMail方法

def getMail(self, host, username, password, port=993):
    try:
        serv = imaplib.IMAP4_SSL(host, port)
    except Exception, e:
        serv = imaplib.IMAP4(host, port)

    serv.login(username, password)
    # MAP4 ID extension 通信规则 RFC 2971 协议 上传ID信息
    imaplib.Commands['ID'] = ('AUTH')
    args = ("name", "XXXX", "contact", "XXXX@163.com", "version", "1.0.0", "vendor", "myclient")
    typ, dat = serv._simple_command('ID', '("' + '" "'.join(args) + '")')
    # 选择邮箱
    serv.select("INBOX")
    # 搜索邮件内容
    typ, data = serv.search(None, 'ALL')
    email_list = []
    for num in data[0].split()[::-1]:
        typ, data = serv.fetch(num, '(RFC822)')
        text = data[0][1]
        message = email.message_from_string(text)  # 转换为email.message对象
        subject_name = self.parseHeader(message)  # 解析邮件首部
        body, attach = self.parseBody(message)  # 解析邮件/信体
        email_list.append({'subject_name': subject_name, 'body': body, 'attach': attach})

    serv.close()
    serv.logout()
    return email_list

解析邮件首部parseHeader方法

def parseHeader(self, message):
    """ 解析邮件首部 """
    subject = message.get('subject')
    h = email.Header.Header(subject)
    dh = email.Header.decode_header(h)
    if dh[0][0] and dh[0][1]:
        subject = unicode(dh[0][0], dh[0][1])
    else:
        if dh[0][0]:
            subject = unicode(dh[0][0])
        else:
            if dh[0][1]:
                subject = unicode(dh[0][1])
            else:
                subject = u'无法解析改标题'
    # 主题
    return subject
    # 发件人
    # print 'From:', email.utils.parseaddr(message.get('from'))[1]
    # 收件人
    # print 'To:', email.utils.parseaddr(message.get('to'))[1]
    # 抄送人
    # print 'Cc:', email.utils.parseaddr(message.get_all('cc'))[1]

解析邮件/信体parseBody方法

def parseBody(self, message):
    """ 解析邮件/信体 """
    body = []
    attach = []
    # 循环信件中的每一个mime的数据块
    for part in message.walk():
        # 这里要判断是否是multipart,是的话,里面的数据是一个message 列表
        if not part.is_multipart():
            charset = part.get_charset()
            # print 'charset: ', charset
            contenttype = part.get_content_type()
            # print 'content-type', contenttype
            name = part.get_param("name")  # 如果是附件,这里就会取出附件的文件名
            if name:
                # 有附件
                # 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC.rar?=这样的文件名
                fh = email.Header.Header(name)
                fdh = email.Header.decode_header(fh)
                fname = fdh[0][0]
                attach_data = part.get_payload(decode=True) # 解码出附件数据,然后存储到文件中
                attach.append((fname, attach_data))
            else:
                # 不是附件,是文本内容
                body.append(part.get_payload(decode=True))  # 解码出文本内容,直接输出来就可以了。
    return body, attach

主体业务resume_collect方法

本例是一个从邮箱获取简历邮件的实现,其他的用法可以根据情况修改主体业务方法
由于实际业务内容太多,所以只拆了主要骨架出来,看起来不是很连贯,不过也不影响理解,具体解析方式还得自己打断点看解析的邮件内容是什么样的。

# 从收件服务器的用户的邮箱中获取邮件信息
def resume_collect(self, server_config):
    email_list = self.getMail(server_config.server, server_config.user, server_config.password)
    for rec in email_list:
        if '51job' in rec['body'][0]:
            try:
                channel = '前程无忧'
                html_obj = etree.HTML(unicode(rec['body'][1], "utf-8"))
                info_xmls = html_obj.xpath('//td/strong')
                name = info_xmls[0].text.replace('\r\n', '').replace(' ', '')
                # 此处通过etree在html中搜寻过滤有效内容
            except:
                channel = '前程无忧'
                name = rec['subject_name']
                down_link = '由于邮件页面改变,当前解析脚本已无法解析,请联系开发人员修复'
        elif '智联' in rec['body'][0]:
            try:
                channel = '智联招聘'
                html_obj = etree.HTML(unicode(rec['body'][1], "utf-8"))
                name = html_obj.xpath('//table/tbody/tr/td/div[@class="call-tip"]/b')[0].text
                # 此处通过etree在html中搜寻过滤有效内容
            except:
                channel = '智联招聘'
                name = rec['subject_name']
                down_link = '由于邮件页面改变,当前解析脚本已无法解析,请联系开发人员修复'
        else:
            name = rec['subject_name']
        if name:
            if rec.get('attach', []):
            	# 获取附件
                for attach_rec in rec['attach']:
                    datas = base64.encodestring(attach_rec[1])
            # 把邮件html转为pdf存入附件
            try:
                for html_rec in rec['body']:
                    if 'html' in html_rec or '<div>' in html_rec:
                        datas = base64.encodestring(pdfkit.from_string(str(unicode(html_rec, "utf-8")), False, options={'encoding': 'UTF-8'}))
                        break
            except:
                pass
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值