zoukankan      html  css  js  c++  java
  • Python接收邮件并保存至MySQL

    参考了一些网络上的资料,做了个简单程序,使用python接收邮件并保存到mysql中。

    代码
    #-------------------------------------------------------------------------------
    #
     Name:        接收邮件模块
    #
     Purpose:
    #
    #
     Author:      garfield
    #
    #
     Created:     15-02-2011
    #
     Copyright:   (c) garfield 2011
    #
     Licence:     <your licence>
    #
    -------------------------------------------------------------------------------
     #_*_encoding:utf-8_*_
    #
    ###源代码用来接收邮件
    import MySQLdb
    import time
    import poplib
    import pickle
    import email,string,sys,os
    from email.Header import Header
    from email.Header import decode_header
    from time import strptime, strftime


    ISOTIMEFORMAT
    ="%Y-%m-%d %X"

    #定义数据库常量
    MySQL_Server="localhost"
    MySQL_User
    ="root"
    MySQL_Password
    ="****"
    MySQL_Database
    ="Python"

    #定义邮件服务器常量
    POP3Sever='pop3.sina.com'
    POP3User
    ='mailuser'
    POP3Password
    ='*****'

    CurMailID
    =-1


    #取信息编码
    def get_charset(message, default="ascii"):
        
    #Get the message charset
        return message.get_charset()
        
    return default

    def SaveMail(Sender,Receiver,Subject,SendDate,ReceiveDate,TextContent,HTMLContent,OriginalMailinfo):
        
    #save mail info to mysql
        Sender=MySQLdb.escape_string(Sender)
        Receiver
    =MySQLdb.escape_string(Receiver)
        Subject
    =MySQLdb.escape_string(Subject)
        TextContent
    =MySQLdb.escape_string(TextContent)
        HTMLContent
    =MySQLdb.escape_string(HTMLContent)
        OriginalMailinfo
    =MySQLdb.escape_string(OriginalMailinfo)
        conn 
    = MySQLdb.connect(MySQL_Server,MySQL_User,MySQL_Password,MySQL_Database,port=3306,connect_timeout=10,compress=True,charset='utf8',use_unicode=True)
        cursor
    =conn.cursor()
        vsql
    ="insert into mail(Sender,Receiver,Subject,SendDate,ReceiveDate,TextContent,HTMLContent,OriginalMailinfo) values('%s','%s','%s','%s','%s','%s','%s','%s')" % (Sender,Receiver,Subject,SendDate,ReceiveDate,TextContent,HTMLContent,OriginalMailinfo) ;
        vsql 
    = vsql.encode('utf8')
        cursor.execute(vsql)
    #一条SQL语句

        vsql 
    = "SELECT max(id) from mail"
        cursor.execute(vsql)
        CurMailID
    =cursor.fetchone()[0]

        conn.commit()
        cursor.close()
        conn.close()

    def SaveMailAtta(vMailID,vFileName,Content,IsInline):
        vFileName
    =MySQLdb.escape_string(vFileName)
        Content
    =MySQLdb.escape_string(Content)
        conn 
    = MySQLdb.connect(MySQL_Server,MySQL_User,MySQL_Password,MySQL_Database,port=3306,connect_timeout=10,compress=True,charset='utf8',use_unicode=True)
        cursor
    =conn.cursor()
        vsql
    ="insert into mailatta(mailid,filename,content,isinline) values('%s','%s','%s','%s')" % (vMailID,vFileName,Content,IsInline) ;
        vsql 
    = vsql.encode('utf8')
        cursor.execute(vsql)
    #一条SQL语句

        conn.commit()
        cursor.close()
        conn.close()


    #解析邮件
    def ParseMail(mail):
      textplain
    =''
      texthtml
    =''
      atta
    ={}
      
    if mail.is_multipart():
          
    for par in mail.walk():
            
    if not par.is_multipart(): # 这里要判断是否是multipart,是的话,里面的数据是无用的,至于为什么可以了解mime相关知识。
                name = par.get_param("name"#如果是附件,这里就会取出附件的文件名

                
    if name:
                    
    #有附件
                    # 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC.rar?=这样的文件名
                    h = email.Header.Header(name)
                    dh 
    = email.Header.decode_header(h)
                    fname 
    = dh[0][0]

                    
    #print '有附件'+fname
                    data = par.get_payload(decode=True) # 解码出附件数据,然后存储到文件中
                    atta[fname]=data
                    
    """
                    try:
                        f = open(fname, 'wb') #注意一定要用wb来打开文件,因为附件一般都是二进制文件
                    except:
                        print '附件名有非法字符,自动换一个'
                        f = open('aaaa', 'wb')
                    f.write(data)
                    f.close()
                    
    """
                
    else:
                    
    #不是附件,是文本内容
                    content_type=par.get_content_type()
                    charset 
    = get_charset(par)
                    
    if content_type in ['text/plain']:
                        
    if charset==None:
                            textplain
    =par.get_payload(decode=True)
                        
    else:
                            textplain
    =par.get_payload(decode=True).decode(charset)
                    
    if content_type in ['text/html']:
                        
    if charset==None:
                            texthtml
    =par.get_payload(decode=True)
                        
    else:
                            texthtml
    =par.get_payload(decode=True).decode(charset)
      
    else:
        type
    =mail.get_content_charset()
        
    if type==None:
            textplain
    =mail.get_payload()
        
    else:
            
    try:
                textplain
    =unicode(mail.get_payload('base64'),type)
            
    except UnicodeDecodeError:
                textplain
    ='Error'

      
    return (textplain,texthtml,atta)

    def main():
        t
    =time.strftime( ISOTIMEFORMAT, time.localtime())

        popClient
    =poplib.POP3(POP3Sever)
        popClient.set_debuglevel(
    1)
        popClient.user(POP3User)
        popClient.pass_(POP3Password)

        numMsgs,mboxSize
    =popClient.stat()

        
    for id in range (numMsgs):
          hdr,message,octet
    =popClient.retr(id+1)
          mail
    =email.message_from_string(string.join(message, '\n'))
          subject
    =mail.get("subject")
          h 
    = email.Header.Header(subject)
          dh 
    = email.Header.decode_header(h)
          subject 
    = dh[0][0]

          FromAddr
    =email.utils.parseaddr(mail['from'])[1]
          ToAddr
    =email.utils.parseaddr(mail['To'])[1]
          mdate
    =mail.get('date')  #'Wed, 16 Feb 2011 14:34:44 +0800'
          mdate=mdate[0:len(mdate)-6]
          
    #:取邮件中的时间进行处理
          md= mktime(strptime(mdate,"%a, %d %b %Y %H:%M:%S"))
          MailDate
    =time.strftime(ISOTIMEFORMAT,time.localtime(md))
          originalmailinfo
    =mail.as_string()
          TextContent,HTMLContent,MailAtta
    =ParseMail(mail)
          
    #保存邮件
          SaveMail(FromAddr,ToAddr,subject,MailDate,MailDate,TextContent,HTMLContent,originalmailinfo)
          
    #保存邮件附件
          #for fk in MailAtta.keys():
          #  SaveMailAtta(CurMailID,fk,MailAtta[fk],False)
        popClient.quit()

    if __name__=='__main__':
        main()


    但附件因为是二进制文件,所以保存到数据库中时需要序列化或进行其他处理,所以以上程序中的附件还不能这么简单地进行保存,需要进一步修改。

    MySQL数据库脚本:

    --
    -- 表的结构 `mail`
    --

    CREATE TABLE IF NOT EXISTS `mail` (
      `ID` int(10) NOT NULL auto_increment,
      `Sender` text,
      `Receiver` text,
      `SendDate` datetime default NULL,
      `ReceiveDate` datetime default NULL,
      `Subject` varchar(500) default NULL,
      `TextContent` text,
      `HTMLContent` text,
      `OriginalMailInfo` text,
      PRIMARY KEY  (`ID`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=546 ;

    --

    --
    -- 表的结构 `mailatta`
    --

    CREATE TABLE IF NOT EXISTS `mailatta` (
      `ID` int(11) NOT NULL auto_increment,
      `MailID` int(11) NOT NULL,
      `filename` varchar(200) NOT NULL,
      `isinline` tinyint(1) NOT NULL,
      `conent` blob NOT NULL,
      PRIMARY KEY  (`ID`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

  • 相关阅读:
    GIL
    CRM2Stark组件
    Django图书管理系统(单表操作)
    Python(ATM机low版)
    Python(9-18天总结)
    Python(1-8天总结)
    Python习题(分页显示)
    Python文本操作2
    Python递归二分法
    Python文本操作
  • 原文地址:https://www.cnblogs.com/GarfieldTom/p/1956153.html
Copyright © 2011-2022 走看看