FTP:网络传输文件
- 需要注意的是,还可以使用
SFTP
协议进行文件的传输,这样会更加安全。有关 Python 的SFTP
模块有 Paramiko 模块以及封装更好的 pystfp 模块。如果需要使用的话,直接学习即可。 - FTP (File Transfer Protocol):文件传输协议,它定义了基于套接字交换命令字符串和文件内容的高级对话模型。FTP 运行着两个套接字层:一个用于命令传输(21端口),一个用于数据传输(一般为20)。Python 中,我们可以使用
ftplib
轻松地使用 FTP 协议完成文件传送的任务。 - 有关 FTP 的主动模式和被动模式的区别请参考 重温FTP的主动模式和被动模式。
- 创建 FTP 对象并且连接到 FTP 服务器:
conn = FTP(site)
conn.login(user, password)
# 可以设置模式
# conn.set_pasv(False)
- 获取二进制文件的函数:
conn.retrbinary('RETR '+ filename, writefile, 1024)
,该函数接收一个回调函数,因此可以再每获取一块数据后存储到文件中。 - 同样,还有另外一个函数
conn.retrlines
处理文本文件。 上传文件:
- 二进制模式:
conn.storbinary('STOR ' + filename, open(filename, 'rb'), 1024)
; - 对应的另外一个函数:
conn.storlines
处理文本文件。
- 二进制模式:
列出远程目录:
conn.nlst()
,与lisdir()
类似。- 关闭 FTP 连接:
conn.quit()
。
电子邮件收发
POP
和IMAP
用于从服务器抓取电子邮件,SMTP
用于发送新消息。 Python 提供的模块:poplib
和imaplib
smtplib
email
:用于解析和构建电子邮件
一般来说,使用
poplib
抓取邮件文本后交给email
模块解析,用email
模块将邮件文本处理后交给smtplib
发送。email
处理的任务包括对地址解析、日期和时间格式化、附件格式化和提取,以及邮件内容的编码和解码等。
获取电子邮件
- 完整使用示例参见 这里,以下是主要代码:
server = poplib.POP3(POP_SERVER)
server.user(MAIL_ADDR)
server.pass_(password)
try:
print(server.getwelcome())
# 查看邮箱状态
msg_count, total_bytes = server.stat()
print('There are {} mails, total bytes are {}.'.format(msg_count, total_bytes))
# 查看邮件列表详情
print(server.list())
# 依次读取每个邮件
for i in range(msg_count):
header, message, bytes = server.retr(i+1)
for line in message:
print(line.decode('utf-8'))
break
except:
server.quit()
- 如果不想一次完整地获取一封邮件的话,可以使用
top(which, N)
函数,它可以获取指定邮件编号的题头部分+后面的N行。这样,抓取的速度就会更快!
发送电子邮件
- SMTP(Simple Mail Transfer Protocol)
- 使用
smtplib
进行简单的文本邮件发送示例参见 这里。 - 主要步骤总结:
server = SMTP(server_addr)
:连接到 SMTP 服务器;- 构建要发送的消息,包括发送的主题、收件人等信息;
server.login(user, passwd)
:登录邮件服务器;server.sendmail()
:发送邮件;server.quit()
:停止与 SMTP 服务器连接。
email 模块
大体上,
email
模块围绕Message
对象,后者提供了如下的功能:- 解析邮件:可以将抓取的邮件解析为一个新的
Message
对象,从而方便访问邮件内容。 - 创建邮件:新的邮件可以通过创建
Message
对象,并调用相关的API完成。它可以帮忙处理格式等方面的问题。最终完成后,可以传递给smtplib
发送出去。
- 解析邮件:可以将抓取的邮件解析为一个新的
Message
对象主要包括三大类信息:- 类型:内容的类型(纯文本、HTML文本、JPEG图像等),编码为一个MIME主类型的一个子类型。
- 题头:类似字典的映射接口,每个键对应一个邮件题头。
- 内容:对于简单消息,是一个字符串(bytes 或 str),对于带有附加或可替代组分的多组分容器类消息,是由一个更多的
Message
对象组成的列表。
简单的示例:
# 构建和解析邮件
>>> from email.message import Message
>>> m = Message()
>>> m['from'] = 'example@gmail.com'
>>> m['to'] = 'example_to@gmail.com'
>>> m.set_payload![](http://)
<bound method Message.set_payload of <email.message.Message object at 0x7fc377c472e8>>
>>> m.set_payload('Hello, world!')
>>> m
<email.message.Message object at 0x7fc377c472e8>
>>> print(m)
from: example@gmail.com
to: example_to@gmail.com
Hello, world!
>>> str(m)
from: example@gmail.com\nto: example_to@gmail.com\n\nHello, world!'
>>> from email.parser import Parser
>>> x = Parser().parsestr(str(m))
>>> x
<email.message.Message object at 0x7fc372d433c8>
>>> x['from']
'example@gmail.com'
>>> for one in x.walk():
x.get_content_type()
x.get_payload()
'text/plain'
'Hello, world!'
- 创建含有多组分邮件的方法:
>>> from email.mime.multipart import MIMEMultipart
>>> from email.mime.text import MIMEText
>>>
>>> top = MIMEMultipart()
>>> top['from'] = 'test@test.com'
>>> top['to'] = 'some@test.com'
>>>
>>> sub1 = MIMEText('Hello, world')
>>> sub2 = MIMEText('\nGood!\n')
>>> sub2.add_header('Name', 'value', filename='data.txt')
>>> top.attach(sub1)
>>> top.attach(sub2)
>>>
>>> top
<email.mime.multipart.MIMEMultipart object at 0x7fc377db2dd8>
- 最后,结合
email
模块编写的一个综合示例参见 此处。该示例主要演示email
模块构建邮件并发送。 运行截图:
收到的邮件: