python實現郵件接收、附件下載
傳送郵件
SMTP協議
SMTP(Simple Mail Transfer Protocol)即簡單郵件傳輸協議,它是一組用於由源地址到目的地址傳送郵件的規則,由它來控制信件的中轉方式。SMTP協議屬於TCP/IP協議簇,它幫助每臺計算機在傳送或中轉信件時找到下一個目的地。通過SMTP協議所指定的伺服器,就可以把E-mail寄到收信人的伺服器上了。
import smtplib
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
def send_email(from_addr, to_addr, subject, password):
msg = MIMEText("郵件正文",'html','utf-8')
msg['From'] = u'<%s>' % from_addr
msg['To'] = u'<%s>' % to_addr
msg['Subject'] = subject
smtp = smtplib.SMTP_SSL('smtp.163.com', 465)
smtp.set_debuglevel(1)
smtp.ehlo("smtp.163.com")
smtp.login(from_addr, password)
smtp.sendmail(from_addr, [to_addr], msg.as_string())
if __name__ == "__main__":
# 這裡的密碼是開啟smtp服務時輸入的客戶端登入授權碼,並不是郵箱密碼
# 現在很多郵箱都需要先開啟smtp才能這樣傳送郵件
send_email(u"from_addr",u"to_addr",u"主題",u"password")
郵箱 | SMTP伺服器 | SSL協議埠 | 非SSL協議埠 |
---|---|---|---|
163 | smtp.163.com | 465或者994 | 25 |
smtp.qq.com | 465或587 | 25 |
接收郵件
POP3和IMAP
POP是指郵局協議,目的是讓使用者可以訪問郵箱伺服器中的郵件,允許使用者從伺服器上把郵件儲存到本地主機(即自己的計算機)上,同時刪除儲存在郵件伺服器上的郵件,而POP3伺服器則是遵循POP3協議的接收郵件伺服器,用來接收電子郵件的。
後來又出現了IMAP協議(Interactive Mail Access Protocol),即互動式郵件訪問協議,與POP3的不同在於:開啟了IMAP後,在電子郵件客戶端收取的郵件仍然保留在伺服器上,同時在客戶端上的操作都會反饋到伺服器上,如:刪除郵件,標記已讀等,伺服器上的郵件也會做相應的動作。
- poplib的常用方法:
方法 | 描述 |
---|---|
POP3(server) | 例項化POP3物件,server是pop伺服器地址 |
user(username) | 傳送使用者名稱到伺服器,等待伺服器返回資訊 |
pass_(password) | 密碼 |
stat() | 返回郵箱的狀態,返回2元祖(訊息的數量,訊息的總位元組) |
list([msgnum]) | stat()的擴充套件,返回一個3元祖(返回資訊, 訊息列表, 訊息的大小),如果指定msgnum,就只返回指定訊息的資料 |
retr(msgnum) | 獲取詳細msgnum,設定為已讀,返回3元組(返回資訊, 訊息msgnum的所以內容, 訊息的位元組數),如果指定msgnum,就只返回指定訊息的資料 |
dele(msgnum) | 將指定訊息標記為刪除 |
quit() | 登出,儲存修改,解鎖郵箱,結束連線,退出 |
from poplib import POP3
p = POP3('pop.163.com')
p.user('xxxxxxx@163.com')
p.pass_('xxxxxxxx')
p.stat()
...
p.quit()
使用IMAP
python中的imaplib包支援IMAP4
常用方法:
方法 | 描述 |
---|---|
IMAP4(server) | 與IMAP伺服器建立連線 |
login(user, pass) | 使用者密碼登入 |
list() | 檢視所有的資料夾(IMAP可以支援建立資料夾) |
select() | 選擇資料夾預設是"INBOX" |
search() | 三個引數,第一的是CHARSET,通常為None(ASCII),第二個引數不知到是幹什麼官方沒解釋 |
import getpass, imaplib
M = imaplib.IMAP4()
M.login(getpass.getuser(), getpass.getpass())
M.select()
typ, data = M.search(None, 'ALL')
for num in data[0].split():
typ, data = M.fetch(num, '(RFC822)')
print 'Message %s\n%s\n' % (num, data[0][1])
M.close()
M.logout()
郵箱: 網易163郵箱,或qq郵箱
# -*- coding: utf-8 -*-
import poplib,email,telnetlib
import datetime,time,sys,traceback
from email.parser import Parser
from email.header import decode_header
from email.utils import parseaddr
class down_email():
def __init__(self,user,password,eamil_server):
# 輸入郵件地址, 口令和POP3伺服器地址:
self.user = user
# 此處密碼是授權碼,用於登入第三方郵件客戶端
self.password = password
self.pop3_server = eamil_server
# 獲得msg的編碼
def guess_charset(self,msg):
charset = msg.get_charset()
if charset is None:
content_type = msg.get('Content-Type', '').lower()
pos = content_type.find('charset=')
if pos >= 0:
charset = content_type[pos + 8:].strip()
return charset
#獲取郵件內容
def get_content(self,msg):
content=''
content_type = msg.get_content_type()
# print('content_type:',content_type)
if content_type == 'text/plain': # or content_type == 'text/html'
content = msg.get_payload(decode=True)
charset = self.guess_charset(msg)
if charset:
content = content.decode(charset)
return content
# 字元編碼轉換
# @staticmethod
def decode_str(self,str_in):
value, charset = decode_header(str_in)[0]
if charset:
value = value.decode(charset)
return value
# 解析郵件,獲取附件
def get_att(self,msg_in, str_day):
attachment_files = []
for part in msg_in.walk():
# 獲取附件名稱型別
file_name = part.get_param("name") # 如果是附件,這裡就會取出附件的檔名
# file_name = part.get_filename() #獲取file_name的第2中方法
# contType = part.get_content_type()
if file_name:
h = email.header.Header(file_name)
# 對附件名稱進行解碼
dh = email.header.decode_header(h)
filename = dh[0][0]
if dh[0][1]:
# 將附件名稱可讀化
filename = self.decode_str(str(filename, dh[0][1]))
# print(filename)
# filename = filename.encode("utf-8")
# 下載附件
data = part.get_payload(decode=True)
# 在指定目錄下建立檔案,注意二進位制檔案需要用wb模式開啟
att_file = open('./test/' + filename, 'wb')
att_file.write(data) # 儲存附件
att_file.close()
attachment_files.append(filename)
else:
# 不是附件,是文字內容
print(self.get_content(part))
# # 如果ture的話內容是沒用的
# if not part.is_multipart():
# # 解碼出文字內容,直接輸出來就可以了。
# print(part.get_payload(decode=True).decode('utf-8'))
return attachment_files
def run_ing(self):
str_day = str(datetime.date.today())# 日期賦值
# 連線到POP3伺服器,有些郵箱伺服器需要ssl加密,可以使用poplib.POP3_SSL
try:
telnetlib.Telnet(self.pop3_server, 995)
self.server = poplib.POP3_SSL(self.pop3_server, 995, timeout=10)
except:
time.sleep(5)
self.server = poplib.POP3(self.pop3_server, 110, timeout=10)
# server.set_debuglevel(1) # 可以開啟或關閉除錯資訊
# 列印POP3伺服器的歡迎文字:
print(self.server.getwelcome().decode('utf-8'))
# 身份認證:
self.server.user(self.user)
self.server.pass_(self.password)
# 返回郵件數量和佔用空間:
print('Messages: %s. Size: %s' % self.server.stat())
# list()返回所有郵件的編號:
resp, mails, octets = self.server.list()
# 可以檢視返回的列表類似[b'1 82923', b'2 2184', ...]
print(mails)
index = len(mails)
for i in range(index, 0, -1):# 倒序遍歷郵件
# for i in range(1, index + 1):# 順序遍歷郵件
resp, lines, octets = self.server.retr(i)
# lines儲存了郵件的原始文字的每一行,
# 郵件的原始文字:
msg_content = b'\r\n'.join(lines).decode('utf-8')
# 解析郵件:
msg = Parser().parsestr(msg_content)
#獲取郵件的發件人,收件人, 抄送人,主題
# hdr, addr = parseaddr(msg.get('From'))
# From = self.decode_str(hdr)
# hdr, addr = parseaddr(msg.get('To'))
# To = self.decode_str(hdr)
# 方法2:from or Form均可
From = parseaddr(msg.get('from'))[1]
To = parseaddr(msg.get('To'))[1]
Cc=parseaddr(msg.get_all('Cc'))[1]# 抄送人
Subject = self.decode_str(msg.get('Subject'))
print('from:%s,to:%s,Cc:%s,subject:%s'%(From,To,Cc,Subject))
# 獲取郵件時間,格式化收件時間
date1 = time.strptime(msg.get("Date")[0:24], '%a, %d %b %Y %H:%M:%S')
# 郵件時間格式轉換
date2 = time.strftime("%Y-%m-%d",date1)
if date2 < str_day:
break # 倒敘用break
# continue # 順敘用continue
else:
# 獲取附件
attach_file=self.get_att(msg,str_day)
print(attach_file)
# 可以根據郵件索引號直接從伺服器刪除郵件:
# self.server.dele(7)
self.server.quit()
if __name__ == '__main__':
#把列印內容輸出到檔案
# origin = sys.stdout
# f = open('./test/log.txt', 'w')
# sys.stdout = f
try:
# 輸入郵件地址, 口令和POP3伺服器地址:
user = '8284@163.com'
# 此處密碼是授權碼,用於登入第三方郵件客戶端
password = '8284'
eamil_server = 'pop.163.com'
# user='xinfei@.com'
# password = 'f67h2'
# eamil_server = 'pop.exmail.qq.com'
email_class=down_email(user=user,password=password,eamil_server=eamil_server)
email_class.run_ing()
except Exception as e:
import traceback
ex_msg = '{exception}'.format(exception=traceback.format_exc())
print(ex_msg)
# traceback.print_exc()
# sys.stdout = origin
# f.close()
遇到的並且待驗證問題:
1、報錯pop3 ConnectionRefusedError: [WinError 10061] 由於目標計算機積極拒絕,無法連線。
一開始直接用的 server = poplib.POP3(pop3_server),所以連線偶爾報錯上面的資訊。
之後改成指定埠和超時時間之後就不再有報錯資訊了
server = poplib.POP3(pop3_server, 110, timeout=10)
or
server = poplib.POP3_SSL(pop3_server, 995, timeout=10)
獲取信體部分
for part in msg.walk():
# 如果ture的話內容是沒用的
if not part.is_multipart():
print(part.get_payload(decode=True).decode('utf-8'))
# 解碼出文字內容,直接輸出來就可以了。
walk()函式能歷遍郵件所有部分,所以通常都把它放到for迴圈裡面使用。然後再使用is_multipart()函式來判斷內容是否有用,列印出有用內容最後用get_payload(decode=True).decode(‘utf-8’)解碼並且列印到控制檯。通常這個迴圈有兩次,第一次是單純的字串格式的,能在控制檯顯示出來的,第二次迴圈列印的是像HTML的格式,能在瀏覽器裡檢視,就像平時看到的郵件那樣。
官方文件:
參考:https://www.cnblogs.com/itogo/p/5910681.html
https://blog.csdn.net/u012209894/article/details/82384987
相關文章
- python 一鍵獲取郵件附件Python
- Python 傳送帶有附件的郵件Python
- python接收郵件的幾種方式Python
- python中使用poplib模組接收郵件Python
- python實現傳送郵件Python
- python實現郵件的傳送Python
- 【python】用SMTP模組傳送帶附件的郵件Python
- Python2.7 smtplib傳送帶附件郵件報錯STARTTLS解PythonTLS
- Python 實現郵件傳送功能(進階)Python
- Python 實現郵件傳送功能(初級)Python
- python實現基於smtp傳送郵件Python
- python 壓縮檔案並進行郵件傳送(附件格式為zip)Python
- win10系統中自帶郵件如何設定接收網易郵箱郵件Win10
- Java實現郵件推送功能Java
- JS實現發郵件功能JS
- SAP Connection inbound郵件接收處理機制
- oracle 傳送郵件 實現方法Oracle
- 在 Laravel 開發環境下,使用框架自帶的 MailHog 來接收郵件。Laravel開發環境框架AIHOG
- C#實現.Net對郵件進行DKIM簽名和驗證,支援附件,傳送郵件簽名後直接投遞到對方伺服器(無需己方郵件伺服器)C#伺服器
- python傳送郵件Python
- python 發個郵件Python
- Spring Boot實現傳送QQ郵件Spring Boot
- 使用JavaMail實現收取和回覆郵件JavaAI
- SpringBoot實現傳送電子郵件Spring Boot
- java 如何實現傳送郵件 email?JavaAI
- Springboot+Javamail實現郵件傳送Spring BootJavaAI
- iOS12系統應用傳送郵件中的附件iOS
- 文字附件屬件
- 如何讓郵附件上雲?分享企業網盤郵附件管理方案
- SpringBoot系列——附件管理:整合業務表單實現上傳、回顯、下載Spring Boot
- 設定手機郵件下載檔案路徑
- Linux平臺mailx發郵件突然出現附件ATT00001.bin的情況總結LinuxAI
- python SMTP郵件服務Python
- Python SMTP傳送郵件Python
- python自動發郵件Python
- 郵件傳送,附件太大怎麼辦 → 那就用分卷壓縮吧
- 如何使用ABAP傳送帶有PDF格式附件的電子郵件
- 在Linux命令列傳送電子郵件附件的兩種方法Linux命令列