1. 程式人生 > >認真對待 Python3 收郵件

認真對待 Python3 收郵件

send 互動 python3.6 地址 lru nco nat 黑名單 from

    • 前言
    • 準備
    • 初體驗
    • 試水
      • 劃水
      • 蹚水
      • 潛水
    • 拓展

前言

之前老是用Python發郵件,用起來挺方便的。但是一直沒實現用Python收郵件,最近忙著筆試面試,但是又不能時刻打開瀏覽器,刷手機看看有沒有新郵件(尤其是有沒有關於面試,筆試通知的郵件)啊。所以寫個腳本來做下定時任務,一旦有相關的主題郵件,結合GUI控件,聲音組件,給出提醒。

想來還是不錯的。

封裝好的客戶端源碼放到了我的GitHub上,有興趣的可以下載下來試一試。

https://github.com/guoruibiao/receive-mails

先來看下效果吧
技術分享圖片


收郵件其實是被Python內置支持的,名為poplib。安裝了Python的話,就會默認存在於標準庫中,用起來也很方便。下面就一步步的來實現今天的任務吧。

準備

由於要使用非官方客戶端的方式來收取郵件,所以需要打開相應的服務。我本人使用的郵箱是163郵箱,其他的郵箱操作也是類似的。如下:

  • 點擊設置

技術分享圖片

  • 開啟pop/smtp/imap協議
    技術分享圖片

  • 先發一封郵件
    給目標郵箱發一封郵件吧。我的內容如下:
    技術分享圖片

至此,準備階段就算是完成了。

初體驗

初體驗嘛,肯定是會比較簡單的了。比如下面我先獲取一些常用的信息:

# coding: utf8

import poplib

# 郵箱個人信息
useraccount = ‘你的郵箱‘
password = ‘你的密碼(註意這個密碼是授權碼,不是你客戶端直接登錄用的密碼)‘
# 郵件服務器地址。如果你的郵箱是163,那麽可以這麽寫。qq的話就是pop.qq.com
pop3_server = ‘pop.163.com‘ # 開始連接到服務器 server = poplib.POP3(pop3_server) # 可選項: 打開或者關閉調試信息,1為打開,會在控制臺打印客戶端與服務器的交互信息 server.set_debuglevel(1) # 可選項: 打印POP3服務器的歡迎文字,驗證是否正確連接到了郵件服務器 print(server.getwelcome().decode(‘utf8‘)) # 開始進行身份驗證 server.user(useraccount) server.pass_(password) # 返回郵件總數目和占用服務器的空間大小(字節數), 通過stat()方法即可
print("Mail counts: {0}, Storage Size: {0}".format(server.stat())) # 使用list()返回所有郵件的編號,默認為字節類型的串 resp, mails, octets = server.list() print("響應信息: ", resp) print("所有郵件簡要信息: ", mails) print("list方法返回數據大小(字節): ", octets) # 關閉與服務器的連接,釋放資源 server.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

運行結果呢?如下:

+OK Welcome to coremail Mail Pop3 Server (163coms[726cd87d72d896a1ac393507346040fas])
*cmd* ‘USER 我的郵箱賬號‘
*cmd* ‘PASS 哈哈不給你看‘
*cmd* ‘STAT‘
*stat* [b‘+OK‘, b‘9‘, b‘52140‘]
Mail counts: (9, 52140), Storage Size: (9, 52140)
*cmd* ‘LIST‘
響應信息:  b‘+OK 9 52140‘
所有郵件簡要信息:  [b‘1 1595‘, b‘2 1631‘, b‘3 1568‘, b‘4 26710‘, b‘5 2851‘, b‘6 6856‘, b‘7 1494‘, b‘8 6685‘, b‘9 2750‘]
list方法返回數據大小(字節):  73
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

試水

經過剛才的初體驗,想必已經會和郵件服務器互動了吧。下面正式開始獲取郵件。

比如我想獲取郵件服務器上其中一封郵件,那麽指定一下索引就可以了。

劃水

# coding: utf8

import poplib
from email.parser import Parser
import base64

def get_parsed_msg():
    # 郵箱個人信息
    useraccount = ‘我的郵箱賬號‘
    password = ‘密碼不告訴你‘
    # 郵件服務器地址
    pop3_server = ‘pop.163.com‘
    # 開始連接到服務器
    server = poplib.POP3(pop3_server)
    # 可選項: 打開或者關閉調試信息,1為打開,會在控制臺打印客戶端與服務器的交互信息
    server.set_debuglevel(1)
    # 可選項: 打印POP3服務器的歡迎文字,驗證是否正確連接到了郵件服務器
    print(server.getwelcome().decode(‘utf8‘))
    # 開始進行身份驗證
    server.user(useraccount)
    server.pass_(password)
    # 使用list()返回所有郵件的編號,默認為字節類型的串
    resp, mails, octets = server.list()
    print(‘郵件總數: {}‘.format(len(mails)))
    # 下面單純獲取最新的一封郵件
    total_mail_numbers = len(mails)
    # 默認下標越大,郵件越新,所以total_mail_numbers代表最新的那封郵件
    response_status, mail_message_lines, octets = server.retr(total_mail_numbers)
    print(‘郵件獲取狀態: {}‘.format(response_status))
    print(‘原始郵件數據:\n{}‘.format(mail_message_lines))
    print(‘該封郵件所占字節大小: {}‘.format(octets))
    msg_content = b‘\r\n‘.join(mail_message_lines).decode(‘gbk‘)
    # 郵件原始數據沒法正常瀏覽,因此需要相應的進行解碼操作
    msg = Parser().parsestr(text=msg_content)
    print(‘解碼後的郵件信息:\n{}‘.format(msg))
    # 關閉與服務器的連接,釋放資源
    server.close()
    return msg

msg = get_parsed_msg()
print(msg)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

獲取到的結果如下:

+OK Welcome to coremail Mail Pop3 Server (163coms[726cd87d72d896a1ac393507346040fas])
*cmd* ‘USER 我的郵箱賬號‘
*cmd* ‘PASS 密碼不告訴你‘
*cmd* ‘LIST‘
郵件總數: 9
*cmd* ‘RETR 9‘
郵件獲取狀態: b‘+OK 2750 octets‘
原始郵件數據:
[b‘Received: from smtpbg323.qq.com (unknown [14.17.32.33])‘, b‘\tby mx38 (Coremail) with SMTP id WMCowEAJ7HMTgthYHvSICA--.9482S3;‘, b‘\tMon, 27 Mar 2017 11:08:03 +0800 (CST)‘, b‘DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512;‘, b‘\tt=1490584083; bh=5mkEI/McRebiKTOSeIfoEIueMTpC8wHHmBUHOC6EIeY=;‘, b‘\th=From:To:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID;‘, b‘\tb=DOHiu0sjQqdYNTqsgSnoUcWztwB0g1xTHHdTJXXShRp8R72USTGblJP6lRU02p2JR‘, b‘\t U4oG22TWhv3IJ3Or9qd1cKqJ8W/3Ya1ih+L1BTfEXhbUE59v1HDA5GjpCc/Cg7aMgA‘, b‘\t PdtmwvW6H45brmgj3P8/KFeOz2GVKTsdZqV8VK1Y=‘, b‘X-QQ-FEAT: Gf8h89u9tNzDNu+6K07CGaVRAG8UpkukGtC6J/Do7Z8trKQlxG+/B3qJrb7U5‘, b‘\tp1QE1l6aary3W8oy+/VAtrDPVFS54LQa27g7fce+ra/0dXGlXVZsqlieRerMeDF/AgwswQF‘, b‘\twZxxr068ee9tfDe5jX7JccTWC1uZPlqzuks9BPjfYmmnzjayMEYch+msiLwNMwLOZba24mn‘, b‘\tucXTswC0032crI2RaLmiBzCuAdeKmZa+L9J6aS9JUD6zihYObJ6l4P/ps97QHqGBEs4MP4c‘, b‘\tFKzdVlvFxtRg3X‘, b‘X-QQ-SSF: 00010000000000F000000000000000Z‘, b‘X-HAS-ATTACH: no‘, b‘X-QQ-BUSINESS-ORIGIN: 2‘, b‘X-Originating-IP: 111.117.136.219‘, b‘X-QQ-STYLE: ‘, b‘X-QQ-mid: webmail585t1490584082t821567‘, b‘From: "=?gb18030?B?ufnosQ==?=" <[email protected]>‘, b‘To: "=?gb18030?B?c3BpZGVyc21hbGw=?=" <[email protected]>‘, b‘Subject: Test for poplib in Python3‘, b‘Mime-Version: 1.0‘, b‘Content-Type: multipart/alternative;‘, b‘\tboundary="----=_NextPart_58D88212_0AF3CB08_64DBF547"‘, b‘Content-Transfer-Encoding: 8Bit‘, b‘Date: Mon, 27 Mar 2017 11:08:02 +0800‘, b‘X-Priority: 3‘, b‘Message-ID: <[email protected]>‘, b‘X-QQ-MIME: TCMime 1.0 by Tencent‘, b‘X-Mailer: QQMail 2.x‘, b‘X-QQ-Mailer: QQMail 2.x‘, b‘X-QQ-SENDSIZE: 520‘, b‘Feedback-ID: webmail:qq.com:bgweb:bgweb125‘, b‘X-CM-TRANSID:WMCowEAJ7HMTgthYHvSICA--.9482S3‘, b‘Authentication-Results: mx38; spf=pass [email protected]; dk‘, b‘\tim=pass [email protected], b‘X-Coremail-Antispam: 1Uf129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73‘, b‘\tVFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUDMUqUUUUU‘, b‘‘, b‘This is a multi-part message in MIME format.‘, b‘‘, b‘------=_NextPart_58D88212_0AF3CB08_64DBF547‘, b‘Content-Type: text/plain;‘, b‘\tcharset="gb18030"‘, b‘Content-Transfer-Encoding: base64‘, b‘‘, b‘SGkgYnJvLg0KDQoNCiBUaGlzIGlzIGEgc2ltcGxlIHRleHQgZm9yIHRlc3RpbmcgcmVjZWl2‘, b‘aW5nIG1haWwgaW4gUHl0aG9uMy4NCiAgICA8YSBocmVmPSdodHRwOi8vYmxvZy5jc2RuLm5l‘, b‘dC9tYXJrc2lub2JlcmcnPk15IEJsb2cgU2l0ZS48L2E+‘, b‘‘, b‘------=_NextPart_58D88212_0AF3CB08_64DBF547‘, b‘Content-Type: text/html;‘, b‘\tcharset="gb18030"‘, b‘Content-Transfer-Encoding: base64‘, b‘‘, b‘PGRpdj48ZGl2PkhpIGJyby48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwO1RoaXMg‘, b‘aXMgYSBzaW1wbGUgdGV4dCBmb3IgdGVzdGluZyByZWNlaXZpbmcgbWFpbCBpbiBQeXRob24z‘, b‘LjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbHQ7YSBocmVmPSdodHRwOi8vYmxvZy5jc2Ru‘, b‘Lm5ldC9tYXJrc2lub2JlcmcnJmd0O015IEJsb2cgU2l0ZS4mbHQ7L2EmZ3Q7PC9kaXY+PC9k‘, b‘aXY+‘, b‘‘, b‘------=_NextPart_58D88212_0AF3CB08_64DBF547--‘, b‘‘]
該封郵件所占字節大小: 2750
解碼後的郵件信息:
Received: from smtpbg323.qq.com (unknown [14.17.32.33])
    by mx38 (Coremail) with SMTP id WMCowEAJ7HMTgthYHvSICA--.9482S3;
    Mon, 27 Mar 2017 11:08:03 +0800 (CST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512;
    t=1490584083; bh=5mkEI/McRebiKTOSeIfoEIueMTpC8wHHmBUHOC6EIeY=;
    h=From:To:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID;
    b=DOHiu0sjQqdYNTqsgSnoUcWztwB0g1xTHHdTJXXShRp8R72USTGblJP6lRU02p2JR
     U4oG22TWhv3IJ3Or9qd1cKqJ8W/3Ya1ih+L1BTfEXhbUE59v1HDA5GjpCc/Cg7aMgA
     PdtmwvW6H45brmgj3P8/KFeOz2GVKTsdZqV8VK1Y=
X-QQ-FEAT: Gf8h89u9tNzDNu+6K07CGaVRAG8UpkukGtC6J/Do7Z8trKQlxG+/B3qJrb7U5
    p1QE1l6aary3W8oy+/VAtrDPVFS54LQa27g7fce+ra/0dXGlXVZsqlieRerMeDF/AgwswQF
    wZxxr068ee9tfDe5jX7JccTWC1uZPlqzuks9BPjfYmmnzjayMEYch+msiLwNMwLOZba24mn
    ucXTswC0032crI2RaLmiBzCuAdeKmZa+L9J6aS9JUD6zihYObJ6l4P/ps97QHqGBEs4MP4c
    FKzdVlvFxtRg3X
X-QQ-SSF: 00010000000000F000000000000000Z
X-HAS-ATTACH: no
X-QQ-BUSINESS-ORIGIN: 2
X-Originating-IP: 111.117.136.219
X-QQ-STYLE: 
X-QQ-mid: webmail585t1490584082t821567
From: "=?gb18030?B?ufnosQ==?=" <1064319632@qq.com>
To: "=?gb18030?B?c3BpZGVyc21hbGw=?=" <spidersmall@163.com>
Subject: Test for poplib in Python3
Mime-Version: 1.0
Content-Type: multipart/alternative;
    boundary="----=_NextPart_58D88212_0AF3CB08_64DBF547"
Content-Transfer-Encoding: 8Bit
Date: Mon, 27 Mar 2017 11:08:02 +0800
X-Priority: 3
Message-ID: <tencent_00BB432438B2D5FF27AA917D@qq.com>
X-QQ-MIME: TCMime 1.0 by Tencent
X-Mailer: QQMail 2.x
X-QQ-Mailer: QQMail 2.x
X-QQ-SENDSIZE: 520
Feedback-ID: webmail:qq.com:bgweb:bgweb125
X-CM-TRANSID: WMCowEAJ7HMTgthYHvSICA--.9482S3
Authentication-Results: mx38; spf=pass smtp.mail=1064319632@qq.com; dk
    im=pass header.i=@qq.com
X-Coremail-Antispam: 1Uf129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73
    VFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUDMUqUUUUU

This is a multi-part message in MIME format.

------=_NextPart_58D88212_0AF3CB08_64DBF547
Content-Type: text/plain;
    charset="gb18030"
Content-Transfer-Encoding: base64

SGkgYnJvLg0KDQoNCiBUaGlzIGlzIGEgc2ltcGxlIHRleHQgZm9yIHRlc3RpbmcgcmVjZWl2
aW5nIG1haWwgaW4gUHl0aG9uMy4NCiAgICA8YSBocmVmPSdodHRwOi8vYmxvZy5jc2RuLm5l
dC9tYXJrc2lub2JlcmcnPk15IEJsb2cgU2l0ZS48L2E+

------=_NextPart_58D88212_0AF3CB08_64DBF547
Content-Type: text/html;
    charset="gb18030"
Content-Transfer-Encoding: base64

PGRpdj48ZGl2PkhpIGJyby48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwO1RoaXMg
aXMgYSBzaW1wbGUgdGV4dCBmb3IgdGVzdGluZyByZWNlaXZpbmcgbWFpbCBpbiBQeXRob24z
LjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbHQ7YSBocmVmPSdodHRwOi8vYmxvZy5jc2Ru
Lm5ldC9tYXJrc2lub2JlcmcnJmd0O015IEJsb2cgU2l0ZS4mbHQ7L2EmZ3Q7PC9kaXY+PC9k
aXY+

------=_NextPart_58D88212_0AF3CB08_64DBF547--

Received: from smtpbg323.qq.com (unknown [14.17.32.33])
    by mx38 (Coremail) with SMTP id WMCowEAJ7HMTgthYHvSICA--.9482S3;
    Mon, 27 Mar 2017 11:08:03 +0800 (CST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512;
    t=1490584083; bh=5mkEI/McRebiKTOSeIfoEIueMTpC8wHHmBUHOC6EIeY=;
    h=From:To:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID;
    b=DOHiu0sjQqdYNTqsgSnoUcWztwB0g1xTHHdTJXXShRp8R72USTGblJP6lRU02p2JR
     U4oG22TWhv3IJ3Or9qd1cKqJ8W/3Ya1ih+L1BTfEXhbUE59v1HDA5GjpCc/Cg7aMgA
     PdtmwvW6H45brmgj3P8/KFeOz2GVKTsdZqV8VK1Y=
X-QQ-FEAT: Gf8h89u9tNzDNu+6K07CGaVRAG8UpkukGtC6J/Do7Z8trKQlxG+/B3qJrb7U5
    p1QE1l6aary3W8oy+/VAtrDPVFS54LQa27g7fce+ra/0dXGlXVZsqlieRerMeDF/AgwswQF
    wZxxr068ee9tfDe5jX7JccTWC1uZPlqzuks9BPjfYmmnzjayMEYch+msiLwNMwLOZba24mn
    ucXTswC0032crI2RaLmiBzCuAdeKmZa+L9J6aS9JUD6zihYObJ6l4P/ps97QHqGBEs4MP4c
    FKzdVlvFxtRg3X
X-QQ-SSF: 00010000000000F000000000000000Z
X-HAS-ATTACH: no
X-QQ-BUSINESS-ORIGIN: 2
X-Originating-IP: 111.117.136.219
X-QQ-STYLE: 
X-QQ-mid: webmail585t1490584082t821567
From: "=?gb18030?B?ufnosQ==?=" <1064319632@qq.com>
To: "=?gb18030?B?c3BpZGVyc21hbGw=?=" <spidersmall@163.com>
Subject: Test for poplib in Python3
Mime-Version: 1.0
Content-Type: multipart/alternative;
    boundary="----=_NextPart_58D88212_0AF3CB08_64DBF547"
Content-Transfer-Encoding: 8Bit
Date: Mon, 27 Mar 2017 11:08:02 +0800
X-Priority: 3
Message-ID: <tencent_00BB432438B2D5FF27AA917D@qq.com>
X-QQ-MIME: TCMime 1.0 by Tencent
X-Mailer: QQMail 2.x
X-QQ-Mailer: QQMail 2.x
X-QQ-SENDSIZE: 520
Feedback-ID: webmail:qq.com:bgweb:bgweb125
X-CM-TRANSID: WMCowEAJ7HMTgthYHvSICA--.9482S3
Authentication-Results: mx38; spf=pass smtp.mail=1064319632@qq.com; dk
    im=pass header.i=@qq.com
X-Coremail-Antispam: 1Uf129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73
    VFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxUDMUqUUUUU

This is a multi-part message in MIME format.

------=_NextPart_58D88212_0AF3CB08_64DBF547
Content-Type: text/plain;
    charset="gb18030"
Content-Transfer-Encoding: base64

SGkgYnJvLg0KDQoNCiBUaGlzIGlzIGEgc2ltcGxlIHRleHQgZm9yIHRlc3RpbmcgcmVjZWl2
aW5nIG1haWwgaW4gUHl0aG9uMy4NCiAgICA8YSBocmVmPSdodHRwOi8vYmxvZy5jc2RuLm5l
dC9tYXJrc2lub2JlcmcnPk15IEJsb2cgU2l0ZS48L2E+

------=_NextPart_58D88212_0AF3CB08_64DBF547
Content-Type: text/html;
    charset="gb18030"
Content-Transfer-Encoding: base64

PGRpdj48ZGl2PkhpIGJyby48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwO1RoaXMg
aXMgYSBzaW1wbGUgdGV4dCBmb3IgdGVzdGluZyByZWNlaXZpbmcgbWFpbCBpbiBQeXRob24z
LjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbHQ7YSBocmVmPSdodHRwOi8vYmxvZy5jc2Ru
Lm5ldC9tYXJrc2lub2JlcmcnJmd0O015IEJsb2cgU2l0ZS4mbHQ7L2EmZ3Q7PC9kaXY+PC9k
aXY+

------=_NextPart_58D88212_0AF3CB08_64DBF547--
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140

這樣就獲取到真正的數據了,對比之後不難發現。未解碼之前和解碼之後,差距還是很大的。

因為Python早已經想到了這一點。所以把原生數據解碼後轉換成email.message.Message對象。這樣我們就可以根據屬性獲取到相應的值了。相比於原生的那些加密的數據,可謂是用心良苦。

蹚水

下面再往下挖一挖,已經獲取到了解碼後的數據了,怎麽提取出我們想要的內容呢?

不妨想一下,我們需要什麽?無非是發件人,收件人,主題,郵件正文。其他的貌似不是很重要了。

再次觀察打印出的數據。不難發現有這樣一串數據:

From: "=?gb18030?B?ufnosQ==?=" <1064319632@qq.com>
To: "=?gb18030?B?c3BpZGVyc21hbGw=?=" <spidersmall@163.com>
Subject: Test for poplib in Python3
  • 1
  • 2
  • 3

對比準備階段的發出的那封郵件,是不是有點眼熟呢?

仔細思考一下發現from等字段是被經過了編碼處理的。而且根據對比From和To字段的格式。發現是

=?編碼?B?base64編碼串?=
  • 1

註意B應該是代表的byte字節類型。於是提取出關鍵部分,我們需要的就是編碼和base64編碼後的串嘛。所以使用split方法就會很輕松了。因為要多次使用這些代碼,所以還是封裝成一個函數的好。

def decode_base64(s, charset=‘utf8‘):
    return str(base64.decodebytes(s.encode(encoding=charset)), encoding=charset)
  • 1
  • 2

獲取解碼後的結果

技術分享圖片

好了,既然這樣就可以了,剩下的To, Subject字段也就可以這樣做了。至於正文部分比較麻煩,待會再聊。

這裏先把代碼寫出來(沒有進行重構呢還,別急。)

def get_details(msg):
    # 保存核心信息的字典,用於返回
    details = {}

    # 獲取發件人詳情
    fromstr = msg.get(‘From‘)
    print(fromstr)
    from_nickname, from_account = get_mail_info(fromstr)
    print(from_nickname, from_account)
    # 獲取收件人詳情
    tostr = msg.get(‘To‘)
    to_nickname, to_account = get_mail_info(tostr)
    print(to_account, to_nickname)

    # 獲取主題信息,也就是標題內容
    subject = msg.get(‘Subject‘)
    print(subject)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

簡單查看一下獲取的結果。

"=?gb18030?B?ufnosQ==?=" <1064319632@qq.com>
郭璞 1064319632@qq.com
spidersmall@163.com spidersmall
Test for poplib in Python3
  • 1
  • 2
  • 3
  • 4

恩,這就可以了。該獲取的也都獲取到了。

潛水

最重要的部分要來了。那就是正文部分。因為正文部分比較特殊,所以處理起來要分而治之。

在163郵箱中,收到的郵件被分為兩部分,一部分是文本信息,另一部分是添加了HTML代碼的形式。但是不管哪一樣,都是我們需要了解的。

還是查看剛才解碼後的數據。

This is a multi-part message in MIME format.

------=_NextPart_58D88212_0AF3CB08_64DBF547
Content-Type: text/plain;
    charset="gb18030"
Content-Transfer-Encoding: base64

SGkgYnJvLg0KDQoNCiBUaGlzIGlzIGEgc2ltcGxlIHRleHQgZm9yIHRlc3RpbmcgcmVjZWl2
aW5nIG1haWwgaW4gUHl0aG9uMy4NCiAgICA8YSBocmVmPSdodHRwOi8vYmxvZy5jc2RuLm5l
dC9tYXJrc2lub2JlcmcnPk15IEJsb2cgU2l0ZS48L2E+

------=_NextPart_58D88212_0AF3CB08_64DBF547
Content-Type: text/html;
    charset="gb18030"
Content-Transfer-Encoding: base64

PGRpdj48ZGl2PkhpIGJyby48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiZuYnNwO1RoaXMg
aXMgYSBzaW1wbGUgdGV4dCBmb3IgdGVzdGluZyByZWNlaXZpbmcgbWFpbCBpbiBQeXRob24z
LjwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbHQ7YSBocmVmPSdodHRwOi8vYmxvZy5jc2Ru
Lm5ldC9tYXJrc2lub2JlcmcnJmd0O015IEJsb2cgU2l0ZS4mbHQ7L2EmZ3Q7PC9kaXY+PC9k
aXY+

------=_NextPart_58D88212_0AF3CB08_64DBF547--
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

是不是發現了Content-type, charset等熟悉的字段呢?這其實就是相關於正文的信息了。

正文信息是被base64編碼後的串,這是因為要做一下安保措施(但是base64不是加密手段,切記切記)。

查閱了官方手冊之後,我發現還是比較容易處理的。如下:

parts = msg.get_payload()
    # print(‘8‘*9, parts[0].as_string())
    content_type = parts[0].get_content_type()
    content_charset = parts[0].get_content_charset()
    # parts[0] 默認為文本信息,而parts[1]默認為添加了HTML代碼的數據信息
    content = parts[0].as_string().split(‘base64‘)[-1]
    print(‘Content*********‘, decode_base64(content, content_charset))
    content = parts[1].as_string().split(‘base64‘)[-1]
    print(‘HTML Content:‘, decode_base64(content, content_charset))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

打印的結果呢?如下:

Content********* Hi bro.


 This is a simple text for testing receiving mail in Python3.
    <a href=‘http://blog.csdn.net/marksinoberg‘>My Blog Site.</a>
HTML Content: <div><div>Hi bro.</div><div><br></div><div>&nbsp;This is a simple text for testing receiving mail in Python3.</div><div>&nbsp; &nbsp; &lt;a href=‘http://blog.csdn.net/marksinoberg‘&gt;My Blog Site.&lt;/a&gt;</div></div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

對比咱們發送的真實的郵件內容。發現沒毛病了。
技術分享圖片

至此,簡單的獲取文本郵件就算是搞定了。

拓展

至於獲取附件等復雜類型的郵件,我還沒做具體的測試,但是大致看了下官方文檔。
技術分享圖片

應該還是不會很難的,畢竟Python。

有點跑偏了,現在已經獲取到郵件相關的詳細內容了,下一步對發件人進行白名單,黑名單的判斷啊也變得很隨意了。

關於內容可以借助貝葉斯來過濾出垃圾郵件,並調用poplib的刪除郵件的方法自動的刪除。

或者統計一下郵件正文的詞頻,借助nltk實現簡單的統計分析。等等吧。

最後,因為Python3.6沒能裝上去pywin32,控件的事就先暫且擱置一下。

最後的最後,來分析一下收郵件的使用場景。其實這個收郵件的作用並不是很大,日常主要是發郵件用的比較多。

但是對於不能時刻查閱重要郵件的場景,比如等待面試,筆試通知。還是比較實用的。

需要源碼的小夥伴,可以在博客下面留下您的郵箱,或者在博客欄目左側找到我的聯系方式與我聯系。
  • 1

晚上再來更新一下。

點我點我

  • 演示動圖
    技術分享圖片

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

認真對待 Python3 收郵件