版权声明:本文为博主原创文章,转载本站文章请注明作者和出处,请勿用于任何商业用途。 https://blog.csdn.net/wutianxu123/article/details/82528339
11.1 文件传输客户端
常见的文件传输因特网协议:文件传输协议(FTP:21)、超文本传输协议(HTTP:80)等。
FTP协议:需要使用用户名密码才能访问远程FTP服务器。流程为:连接-登录-使用-退出。
使用模块及语法:
import ftplib
FTP类中常用的方法:
方法 | 解释 |
---|---|
login() | 登录FTP服务器,所有参数都是可选的 |
pwd() | 获得当前工作目录 |
cwd(path) | 把当前工作目录设置为path所示的路径 |
dir() | 显示path目录里的内容 |
nlst() | 与dir()类似, 但返回一个文件名列表 |
retrlines() | 给定FTP命令,用于下载文本文件 |
retrbinary() | 与retrlines()类似,这个指令处理二进制文件 |
storlines() | 给定FTP命令,用来上传文本文件。要给定一个文件对象f |
storbinary() | 与storlines()类似,该指令处理二进制文件。要给定一个文件对象f |
rename(old, new) | 把远程文件old重命名为new |
delete(path) | 删除位于path的远程文件 |
mkd() | 创建远程目录 |
rmd() | 删除远程目录 |
quit() | 关闭连接并退出 |
代码实例:注意!此为win7下自建的FTP服务器!
# -*- coding: UTF-8 -*-
import ftplib #加载相关模块
import os
import socket
#下载文件:C:\FTPceshi\one\two\xixixi.txt
HOST = '192.168.88.136' #FTP服务器地址。设置绑定C:\FTPceshi
DIRN = 'one/two' #中间路径。 FTP服务器有默认的首路径,其下会存在文件夹或文件
FILE = 'xixixi.txt' #最后文件名
def main():
try: #创建一个FTP对象,尝试连接到FTP服务器,然后返回
f = ftplib.FTP(HOST) #连接FTP服务器
except (socket.error, socket.gaierror) as e: #前面是异常类型,后面是变量用于接收异常。as可用可不用
print u'错误!没有搜索到地址: "%s"' % HOST
return
print u'成功连接到地址: "%s"' % HOST
try: #尝试用“Anonymous”登录,不行就结束
f.login('Anonymous', '[email protected]') #如果匿名登录则用空字符串代替即可
except ftplib.error_perm: #此处指定了异常类型,没有使用变量接收异常。变量也是可用可不用。变量接收异常就是为了方便记录
print u'错误!不能匿名登录'
f.quit()
return
print u'使用"Anonymous"登录成功'
try: #转到发布目录
f.cwd(DIRN) #把当前工作目录设置为 DIRN 所示的路径
except ftplib.error_perm: #此处指定了异常类型,没有使用变量接收异常
print u'错误!不能这样操作目录: "%s"' % DIRN
f.quit()
return
print u'成功操作目录:"%s" ' % DIRN
try: #下载文件。此时已到指定目录下
f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)
#向retrbinary()传递了一个回调函数,每接收到一块二进制数据的时候都会调用这个回调函数
#这个函数就是创建文件的本地版本时需要用到的文件对象的write()方法
except ftplib.error_perm:
print u'错误!不能读取文件"%s"' % FILE
os.unlink(FILE) #如果由于某些原因无法保存文件,则移除空的文件来避免弄乱文件系统
else:
print u'成功下载到文件:"%s"' % FILE #下载到与脚本同一目录下
f.quit() #为了避免另外两行关闭FTP连接并返回,使用了else语句
if __name__ == '__main__': #运行独立脚本的惯用方法
main()
11.2 网络新闻客户端
网络新闻传输协议NNTP:在新闻组中发表或下载帖子。端口:119
流程:连接-登录(可选)-使用-退出
使用模块及语法:
import nntplib
NNTP类中常用的方法:
方法 | 解释 |
---|---|
group(name) | 选择一个组的名字,返回一个元组(rsp,ct,fst,lst,group),分别表示服务器响应信息、文章数量、第一个和最后一个文章的编号、组名,所有数据都是字符串 |
xhdr() | 返回文章范围 artrg(“头-尾”的格式)内文章 hdr 头的列表 |
body() | 根据 id 获取文章正文,返回一个元组(rsp, anum, mid, data)分别表示服务器响应信息、文章编号、消息 ID、文章所有行的列表 |
head(id) | 与 body()类似,返回相同的元组,只是返回的行列表中只包括文章标题 |
article(id) | 与 body()类似,返回相同的元组,只是返回的行列表中同时包括文章标题和正文 |
stat(id) | 让文章的“指针”指向id。返回一个与body()相同的元组(rsp, anum,mid),但不包含文章的数据 |
next() | 和stat()类似,把文章指针移到下一篇文章,返回与stat()相似的元组 |
last() | 和stat()类似,把文章指针移到最后一篇文章,返回与stat()相似的元组 |
post(ufile) | 上传ufile文件对象里的内容,并发布到当前新闻组中 |
quit() | 关闭连接并退出 |
代码实例: 注意!该NNTP服务器为网络寻找且可用!
# -*- coding: UTF-8 -*-
import nntplib
import socket
host="web.aioe.org" #新闻组地址(经测试可用)
grnm="comp.lang.python" #新闻主题命名。comp开头的是以计算机专业为主的
user="yonghuming" #登录新闻组用户口令。本例中未使用
password="mima" #不能用pass,因为是关键字
def main():
try: #尝试登录新闻组服务器,如果失败则退出
n=nntplib.NNTP(host)
except socket.gaierror as e: #捕获异常,变量用于接收异常
print u"错误:没有搜索到地址:'%s'"% host
print "('%s')"% eval(str(e))[1] #e接收了异常信息,此时将其输出。如果该行注释,将不输出任何异常信息
return
except nntplib.NNTPPermanentError as e: #捕获另外一个异常。
print u"错误:地址拒绝访问:'%s'"% host
print "('%s')"% str(e)
return
print u"成功连接到地址:'%s'" % host #没有异常则执行
try:
rsp,ct,fst,lst,grp=n.group(grnm) #读取新闻主题内容。具体见方法表
except nntplib.NNTPTemporaryError as ee: #捕获异常
print u"错误:不能加载新闻主题:'%s'"% grnm
print "('%s')"% str(e) #输出此时的异常
print u"服务器需要身份验证"
print u"登录超时"
n.quit() #从服务器注销
return
except nntplib.NNTPTemporaryError as ee: #捕获异常
print u"新闻主题未能获得:'%s'"% grnm
print "('%s')"% str(e)
n.quit() #从服务器注销
return
print u"发现新闻主题:'%s'"% grnm
rng = "%s-%s"% (lst,lst)
rsp,frm = n.xhdr('from',rng) #定义来自(作者)变量
rsp,sub = n.xhdr('subject',rng) #定义主题变量
rsp,dat = n.xhdr('date',rng) #时间时间变量
print '''found last article (#%s):
from:%s
subject:%s
date:%s
'''%(lst,frm[0][1],sub[0][1],dat[0][1])
rsp,anum,mid,data=n.body(lst) #下载文章的内容。具体见方法表
displayfirst20(data) #定义函数,使其至多显示前20行
n.quit() #从服务器注销
def displayfirst20(data): #空行若过多只显示第一个空行
print "first (<=20) meaningful lines:\n"
count=0 #计数器清零
lines=(line.rstrip() for line in data) #rstrip只能删去串尾的空格。因为串首或串中的空格可能是代码
lastblank=True #定义空行。空行为True
for line in lines:
if line: #当前不是空行则执行
lower=line.lower() #将所有字符串转换为小写,此时将不区分大小写
if (lower.startswith('>') and not \ #如果以">"或"|"开头,说明是一个引用
lower.startswith('>>>'))or \ #以">>>"开头可能是交互环境
lower.startswith('|') or \
lower.startswith('in article') or \ #以in article开头
lower.endswith('writes:') or \ #以writes或wrote结尾都是引用文本
lower.endswith('wrote:'):
continue #跳过以上内容
if not lastblank or (lastblank and line): #上一行不为空或当前行不为空则显示
print '%s'% line
if line:
count +=1 #遇到不是空行计数器加1
lastblank =False #设为False,表示这行不是空行
else:
lastblank=True
if count==20: #遇到20个不是空行的就退出。让只显示20行文章
break
if __name__ == '__main__':
main()
11.3 电子邮件客户端
发送电子邮件:简单邮件传输协议SMTP。流程为:连接-登录(可选)-使用-退出
接收电子邮件:邮局协议第三版POP3。流程为:连接-登录-使用-退出。此处不做示例讲解
使用模块及语法:
import smtplib #导入模块
from email.mime.text import MIMEText #此函数可以显示邮件文本
from email.mime.multipart import MIMEMultipart #此模块函数可以添加附件
from email.header import Header #此函数可以显示邮件标题
from email.mime.image import MIMEImage #此函数可以添加图片
SMTP类中常用的方法:
方法 | 解释 |
---|---|
sendmail() | 将 msg从from发送至to(以列表或元组表示) |
ehlo()或 helo() | 使用EHLO或HELO初始化SMTP或ESMTP服务器的会话 |
starttls() | 让服务器启用TLS模式 |
set_debuglevel(level) | 为服务器通信设置调试级别。可以看到具体信息 |
quit() | 关闭连接并退出 |
login(user, passwd) | 使用用户名和密码登录SMTP服务器 |
代码实例:
# -*- coding: UTF-8 -*-
import smtplib #导入模块
from email.mime.text import MIMEText #此函数可以显示邮件文本
from email.mime.multipart import MIMEMultipart #此模块函数可以添加附件
from email.header import Header #此函数可以显示邮件标题
from email.mime.image import MIMEImage #此函数可以添加图片
mail_host = "smtp.163.com" #设置邮件服务器
mail_user = "[email protected]" #设置用户名
mail_pass = "12345678" #设置口令。注意!通常使用第三方应用发送邮件需要的不是密码,而是授权码,此处为授权码
sender = '[email protected]' #发送邮件
receivers = ['[email protected]'] #接收邮件。此处我自己给自己发邮件
#注意!多形式邮件应将所有内容都放在这里。如果不同形式分开存放,则多形式不能同时发送。
mail_msg = """
<p>Python邮件正文……</p>
<p><a href="https://www.baidu.com">邮件测试连接。连接到百度</a></p>
<p>图片如下:</p>
<p><img src="cid:image1"></p>
"""
#创建常规文本邮件及邮件链接
message = MIMEMultipart() #创建带附件的实例
message.attach(MIMEText(mail_msg,'html','utf-8')) #邮件正文。此处格式为html(以网页形式显示)。如果是纯正文,格式应为:plain(如果有网页形式的则同代码一块显示)。它可以让正文正常显示,否则显示乱码
message['From'] = Header("我是发件人",'utf-8') #发件人标题,为空则标题为空
message['To'] = Header("我是收件人",'utf-8') #收件人标题
subject = 'Python邮件名字' #邮件名
message['Subject'] = Header(subject,'utf-8') #邮件主题,不设置则无主题。主题是邮件上面显示的标题
#创建邮件附件
att1 = MIMEText(open('xixixi.txt','rb').read(),'base64','utf-8') #传送当前目录下的xixixi.txt文件
att1["Content-Type"] = 'application/octet-stream' #邮件附件文件类型
att1["Content-Disposition"] = 'attachment; filename="xixixi.txt"' #这里的filename可以任意写,写什么名字,邮件中显示什么名字
message.attach(att1) #添加附件完成
#创建邮件图片
fp = open('baidu.png','rb') #打开和脚本同目录下的图片
msgImage = MIMEImage(fp.read()) #读取图片
fp.close()
msgImage.add_header('Content-ID','<image1>') #邮件图片类型
message.attach(msgImage) #添加图片完成
try:
smtpObj = smtplib.SMTP() #发送邮件
smtpObj.connect(mail_host, 25) #连接邮件服务器地址,25为SMTP端口号
smtpObj.login(mail_user,mail_pass) #登录邮件服务器
smtpObj.sendmail(sender, receivers, message.as_string()) #发件人账号、收件人账号、邮件具体信息
print u"邮件发送成功"
except smtplib.SMTPException: #捕获异常
print u"Error: 无法发送邮件"