Python 网络客户端编程
如果我们把因特网简化成一个数据交换中心,数据交换的参与者是一个服务提供者和一个服务的使用者。服务器就是服务者,或叫生产者,它提供服务,一般只有一个服务器,和多个消费者。因特网中最流行的事情就是文件的交换。文件交换无处不在。
文本传输协议(FTP)主要用于匿名下载公共文件,也可以用于在两台电脑之间传输文件。
下面这个例子简单写了一个连接FTP并下载文件
#!/usr/bin/ env python
#coding=utf-8
import ftplib
import os
import socket
HOST = 'ftp.sjtu.edu.cn'
DIRN = 'pub/rfc/fyi/'
FILE = 'fyi10.txt'
def main():
try:
f = ftplib.FTP(HOST)
except (socket.error, socket.gaierror), e:
print('ERROR: cannot reach "%s"' % HOST)
return
print('***Connected to host "%s"' % HOST)
try:
f.login()
except ftplib.error_perm:
print('ERROR: cannot login anonymously')
f.quit()
return
print('*** Logged in as "anonymously"')
try:
f.cwd(DIRN)
except ftplib.error_perm:
print('ERROR: cannot cd to "%s"' % DIRN)
f.quit()
return
print('*** Changed to "%s" folder' %DIRN)
try:
f.retrbinary('RETR %s' %FILE, open(FILE, 'wb').write)
except ftplib.error_perm:
print('ERROR: cannot read file "%s"' % FILE)
os.unlink(FILE)
else:
print('*** Downloaded "%s" to CWD' %FILE)
f.quit()
return
if __name__ == '__main__':
main()
网络新闻传输协议(NNTP)与FTP的操作方式很像,而且简单的多。FTP需要用不同的端口来做登录,数据传输和控制,而NNTP只使用一个标准端口119来做通讯。
我们来下载Python语言新闻组com.lang.python里的一篇文章。
#!/usr/bin/ env python
#coding=utf-8
import nntplib
import socket
HOST = 'your.nntp.server'
GRNM = 'group name'
USER = 'user'
PASS = 'password'
def displayFirst20(data):
'''
获取 data 内前20个有意义的行
'''
print('*** first (<=20) meaningful lines:\n')
count = 0 #创建一个计数器
'''
获取文章行列表,rstrip()方法删除字符串尾随的空格
'''
lines = (line.rstrip() for line in data)
lastBlank = True #上一行为空的标识,作为判断条件
for line in lines:
if line:
lower = line.lower() #将 line 内容转换小写
if (lower.startswith('>') and not \
lower.startswith('>>>')) or \
lower.startswith('|') or \
lower.startswith('in article') or \
lower.endswith('writes:') or \
lower.endswith('wrote:'):
continue
if not lastBlank or (lastBlank and line): #如果上一行不是空行,或者上一行为空行,但当前行不为空时
print(' %s' % line)
if line: #如果当前行不为空,计数器+1,lastBank 为 false,上一行不为空
count += 1
lastBlank = False
else:
lastBlank = True
if count == 20:
break
def main():
try:
n = nntplib.NNTP(HOST) #尝试连接 NNTP 服务器,如果失败就退出
#,user=USER,password=PASS
except socket.gaierror as e:
print('ERROR:cannot reach host "%s"' % HOST)
print(' ("%s")' % eval(str(e))[1])
return
except nntplib.NNTPPermanentError as e:
print('ERROR:access denied on "%s"' % HOST)
print(' %s' % str(e))
return
print('****connected to host "%s"' % HOST)
try:
rsp, ct , fst, lst, grp = n.group(GRNM) #尝试读取指定的新闻组
except nntplib.NNTPTemporaryError as e: #如果新闻组不存在、或服务器没有保存这个新闻组,或需要身份验证等就退出
print('ERROR: cannot load group "%s"' % GRNM)
print(' "%s"' % str(e))
print(' server may require authentication')
print(' uncomment/edit login line above')
n.quit()
return
except nntplib.NNTPTemporaryError as e:
print('ERROR: group "%s" unavaliable' % GRNM)
print(' %s' % str(e))
n.quit()
return
print('*** found newsgroup "%s"' % GRNM)
rng = '%s-%s' % (lst,lst) #给定想要提取消息头的文章范围,因为要获取最后一条信息,所以范围是最后--最后
rsp, frm = n.xhdr('from',rng) #获取制定范围的文章信息:服务器响应,指定范围的消息头列表 frm-文章来源
rsp, sub = n.xhdr('subject',rng) #sub 文章子标题
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]))
'''
由于上边选取的范围只有最后一个,所以只获取第一个元素【0】,数
据元素是一个长度为2的元组,包含文章编号和数据字符串,因此数据字符串frm[0][1]
'''
rsp, anum, mid, data = n.body(lst) #根据最后一篇文章的 id 获取(服务器响应信息,文章编号,消息 id,文章所有行)
displayFirst20(data) #调用方法只保存前20个有意义的行
n.quit() #退出
if __name__ == '__main__':
main()
电子邮件e-mail
SMTP(简单邮件传输协议)是在因特网上MTA之间用于信息交换的最常用的MTS。它被MTA用来把e-mail从一台主机传送到另一台主机。在发送email的时候,必须要连接到一个外部的SMTP服务器,这时,你的邮件程序是一个SMTP客户端。
POP(邮局协议),让用户的工作站可以访问邮箱服务器里的邮件。邮件要能从工作站通过SMTP发送到邮件服务器。POP3指的是POP协议最常用的第三版。
#!/usr/bin/ env python
#coding=utf-8
from smtplib import SMTP
from smtplib import SMTPRecipientsRefused
from poplib import POP3
from time import sleep
import sys
smtpserver = 'smtp.163.com'
pop3server = 'pop.163.com'
emailaddr = 'username@163.com'
username = 'username'
password = 'password'
# 组合邮件格式
origHeaders = ['From: username@163.com',
'To: username@163.com',
'Subject: test msg']
origBody = ['test ', 'smtp', 'pop3']
origMsg = '\r\n\r\n'.join(['\r\n'.join(origHeaders), '\r\n'.join(origBody)])
# 发送邮件部分
def sendMail():
sendSer = SMTP(smtpserver)
sendSer.set_debuglevel(1)
print sendSer.ehlo()[0] # 服务器属性等
sendSer.login(username, password) # 邮箱需要验证
try:
errs = sendSer.sendmail(emailaddr, emailaddr, origMsg)
except SMTPRecipientsRefused:
print 'server refused....'
sys.exit(1)
sendSer.quit()
assert len(errs) == 0, errs
print '******send a mail ....OK!'
sleep(10) # 等待10秒
print '******Now get the mail .....*******'
# 开始接收邮件
def receiveMail():
revcSer = POP3(pop3server)
revcSer.user(username)
revcSer.pass_(password)
rsp, msg, siz = revcSer.retr(revcSer.stat()[0])
sep = msg.index('')
if msg:
for i in msg:
print i
revcBody = msg[sep + 1:]
assert origBody == revcBody
print '******successful get ....'
def main():
sendMail()
receiveMail()
if __name__ == '__main__':
main()
还没有评论,来说两句吧...