Python:郵件:outlook:基本用法

零、前情提要

最近編寫自動化郵件監控時,因爲公司的郵箱是outlook, 自動化有兩種方式, 這邊記錄一下已被以後使用html

1、協議用法

1.1 郵件路徑概述

1.1.1 發送電子郵件的過程

發件人 —> MUA -> MTA -> 若干個MTA - MDA <- MUA <- 收件人python

發件人經過電子郵件軟件MUA將郵件傳輸給本電子郵件的Email服務提供商,好比說@163.com則會傳遞給網易的服務器MTA,再由服務提供商投遞到對方的服務器MDA存儲,若是郵件的接收方是@sina.com則投遞到新浪的服務器MDA上, 若是對方要收取郵件, 則須要經過MUA從對應的MDA中提取郵件.編程

郵件的內容其實都存在MUA上, 即從電子郵箱軟件看到的內容. 操做電子郵件軟件的郵件就是直接操做MUA上的內容.windows

1.1.2 郵件概述

名詞 釋義
MUA Mail User Agent, 電子郵件軟件, 好比outlookfoxmail
MTA Mail Transfer Agent, 郵件傳輸代理,即Email服務提供商,好比網易、新浪
MDA Mail Delivery Agent, 郵件投遞代理, 即服務提供商的服務器

1.1.3 協議概述

有了以上的概念, 那麼收發郵件的本質就是:安全

  • 編寫MUA把郵件發送到MTA. 此時使用的協議就是SMTP協議.
  • 編寫MUAMDA上收郵件.

在郵件客戶端在發送郵件時會先配置SMTP服務器, 也就是須要發到哪一個MTA上. 若是此時你用的是@163.com,則只能發也必須發到網易的MTA, 新浪的MTA是不服務網易的用戶的. 爲了驗證你是網易的用戶, 所以SMTP服務器要求提供郵件地址和郵件口令.服務器

1.2 協議用法介紹

協議名 釋義
MIME 多用途互聯網郵件擴展類型。是設定某種擴展名的文件用一種應用程序來打開的方式類型
SMTP Simple Mail Transfer Protocol, 郵件發送協議,創建在FTP文件傳輸服務上的一種郵件服務.
POP Post Office Protocol, 目前的版本是3, 俗稱POP3; 郵件接收協議, 本協議主要用於支持使用客戶端遠程管理在服務器上的電子郵件。
IMAP Internet Message Access Protocol, 目前版本是4, 交互郵件訪問協議, 它的主要做用是郵件客戶端能夠經過這種協議從郵件服務器上獲取郵件的信息,下載郵件, 直接操做MDA上存儲的郵件,好比從收件箱一道垃圾箱.

1.2 導入

## pop協議
import poplib ## python內置庫

## 郵件解析
from email.parser import Parser ## 解析郵件原始文本
from email.header import decode_header
from email.utils import parseaddr

## smtp協議
import smtplib

## 郵件構造
from email.mime.text import MIMEText
複製代碼

1.3 POP3協議

pop3協議收取的不是一個能夠閱讀的郵件自己, 而是郵件的原始文本, 須要使用email模塊提供類來解析原始文本, 變成可閱讀的郵件對象.app

1.3.1 登陸郵箱

## 基礎配置
email_address = 'xxx@outlook.com'
email_password = 'xxxx'
pop_server_host = 'partner.outlook.cn' ## 公司級(office365)的連接地址, 我的申請的可能不一樣
pop_server_port = 995 ## 端口

## 登陸郵件
### 連接pop服務器
email_server = poplib.POP3_SSL(host=pop_server_host, port=pop_server_port, timeout=10)
email_server = poplib.POP3(host=pop_server_host, port=pop_server_port, timeout=10)

### 驗證郵箱是否存在
email_server.user(email_address)

### 驗證郵件密碼是否正確
email_server.pass_(email_password)
複製代碼

1.3.2 獲取郵件

## 返回郵件數量和佔用空間
email_server.stat()

## 返回郵件編號
resp, mails, octets = email_server.list()

## 返回郵件數量
index = len(mails)

## 獲取特定序號郵件, 索引從1開始
resp, lines, octets = email_server.retr(index) ## lines 儲存郵件原始文本全部信息.

## 獲取郵件原始文本
email_content = b'\r\n'.join(lines).decode('utf-8')

## 解析郵件文本
## 解析爲`Message`對象, 此時對象自己多是一個`MIMEMultipart`對象, 即包含嵌套的其餘`MIME`對象, 嵌套可能還不止一層.
content = Parser().parsestr(email_content) 
複製代碼

1.3.3 刪除郵件及其餘

## 刪除郵件
## 經過郵件索引號直接從服務器刪除郵件.
email_server.dele(index)

## 關閉鏈接
email_server.quit()
複製代碼

1.4 MIME解析

MIME(Multipurpose Internet Mail Extensions): 描述消息內容類型的因特網標準, 能包含文本、圖像、音頻、視頻以及其餘應用程序專用的數據ui

MIME參考手冊: www.w3school.com.cn/media/media…編碼

1.4.1 MIME示例

類型/子類型 擴展名
application/pdf pdf
image/jpeg jpe/jpg/jpeg

1.4.2 郵件解析

## Suject解析
## 郵件的Subject或者Email中包含的名字都是通過編碼後的str, 要正常顯示, 就必須decode.
def decode_str(s):
    value, charset = decode_header(s)[0] ## decode_header()返回的是一個list, 抄送多人時會返回多個元素. 能夠用索引選擇對應元素.
    if charset: ## charset是獲得的編碼類型
        value = value.decode(charset)
    
    return value

## 獲得對應元素好比說收件人、發件人的原始文本值
for header in ['From','To','Subject']
    content = content.get(header,'')
    
## Subject解析
value  = decode_str(value) ## 此時header = 'Subject'
複製代碼
## From、To解析 發件人、收件人解析
hdr, addr = parseaddr(value) ## 此時header in ('From','To')
name = decode_str(hdr)
複製代碼
## 郵件正文解析
## 郵件文本也是str,須要檢測編碼,不然非utf-8編碼的郵件沒法正常顯示
## 編碼確認
def guess_charset(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
    
## 正文解析
content_type = content.get_content_type()
if content_type = 'text/plain' or content_type = 'text/html':
    content_email = content.get_payload(decode=True)
    charset = guess_charset(content)
    if charset:
        content_email = content_email.decode(content)
複製代碼

1.5 SMTP協議

PythonSMTP支持有smtplibemail兩個模塊,email負責構建郵件,smtplib負責發送郵件.spa

1.5.1 基礎用法

## 基礎數據
### 發件人 密碼 收件人 服務器
from_addr = 'xxx@163.com'
password = 'xxxx'
to_addr = 'xxx@outlook.com'
smtp_server = 'smtp.163.com'

## 構建基礎文件
def _format_addr(s):
    name, addr = parseaddr(s)
    return formataddr((Header(name,'utf-8').encode(), addr))


msg = MIMEText('hello, send by Python...','plain','utf-8')
msg['From'] = _format_addr('name <%s>' % from_addr)
msg['To'] = _format_addr('name <%s>' % to_addr)
msg['Subject'] = Header('來自SMTP的問候...','utf-8').encode()

## 郵件發送
server  = smtplib.SMTP(smtp_server,25) # SMTP協議默認端口是25, 25端口是明文傳輸 若是要SSL安全鏈接 則須要: server.starttls()
server.ser_debuglevek(1) ## 打印初和SMTP服務器交互的全部信息
server.login(from_addr,password)
server.sendmail(from_addr, [to_addr], msg.as_string()) ## 郵件正文是一個`str` as_string()把MIMEText對象變成`str`.
server.quit()
複製代碼

2、配置用法

2.1 配置用法介紹 - 只適用於window

配置用法的核心是經過pywin32(python for windows)庫調用本地outlook配置(office提供基於COM接口的編程)進行郵件讀取, 但會存在一個問題讀取配置須要受權, 受權方法一是會喚起受權窗口進行短期臨時受權, 二是經過後臺配置進行永久受權.

2.2 導入

## pip install pywin32
import win32com
複製代碼

2.3 基本配置

## 啓動outlook進程
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") ## Dispatch派遣 即調用Outlook.Application.

## 獲取配置中全部帳號
accounts = win32com.client.Dispatch("Outlook.Application").Session.Accounts

## 獲取一級目錄
inbox = outlook.Folders(account.DeliveryStore.DisplayName)
folders = inbox.Folders
複製代碼
相關文章
相關標籤/搜索