17.6 练习

FTP

17-1.简单FTP客户端。参考本章的FTP例子,写一个小的FTP客户端程序,能够去你喜欢的网站下载你使用的软件的最新版本。这个脚本应该每几个月就运行一次,以确保你在用的软件是“最新和最好的”。你应该把FTP地址,登录信息放在一个表里,省得每次都要修改。

17-2.简单FTP客户端和模式匹配。在上一个练习的基础上创建一个新的FTP客户端程序。它可以上传和下载指定模式的文件。比方说,如果想把一些Python的文件和PDF文件从一台电脑传到另一台电脑上,那用户可以输入“.py”或“doc.pdf”,程序会只传这些文件名匹配的文件。

17-3.智能FTP命令行客户端程序。创建一个跟Unix下/bin/ftp类似的命令行下的FTP程序,不过,这个FTP客户端要更好一些,能提供更有用的功能。你可以看看http://ncftp.com的ncFTP作为样板。它有以下功能:历史记录、书签(可以保存FTP地址和登录信息)、下载进度显示等。你可以使用readline来记录历史命令,用curses来控制屏幕。

17-4.FTP和多线程。创建一个能使用Python的线程库下载文件的FTP客户端程序。你可以通过修改上一个练习的程序或者重写一个简单的客户端来下载文件。你可以在命令行参数里指定要下载的文件,也可以做一个GUI,在界面中让用户选择要下载的文件。附加题:要能支持模式,如.exe。要使用不同的线程来下载每个文件。

17-5.FTP和GUI。在你上面写的FTP客户端程序中加入GUI,让你的程序成为一个完整的FTP应用程序。你可以使用Python的任何GUI工具包。

17-6.子类化。从ftplib. FTP派生出一个类FTP2,在这个类中,你不用像之前那4个retr()和stor()方法中那样要给定“STOR filename”或“RETR filename”这样的命令,只要传文件名就好了。你可以重写已有的方法也可以在方法后加一个2,如retrlines2()。Python发布包中有一个Tools/scripts/ftpmirror.py脚本,它使用ftplib模块,可以对整个FTP站点或FTP站点的一部分做镜像。它可以作为ftplib模块应用的扩展例子来使用。解答下面5个问题时,可以参考这个脚本。你可以直接使用ftpmirror.py里的代码,也可以以这个脚本为样板,自己重新写一个。

17-7.递归。ftpmirror.py脚本递归的复制一个远程的目录。写一个与ftpmirror.py相似的脚本,它的默认行为是不递归的。只有在传入了“-r”参数的时候,才递归的把文件复制到本地目录。

17-8.模式匹配。ftpmirror.py脚本支持”-s”参数让用户指定能匹配模式的文件不下载,如“.exe”。重新写一个简单的FTP客户端程序或修改之前的程序,实现让用户指定通配符程序只下载能匹配模式的文件。可以在你之前练习的答案基础上实现。

17-9.递归和模式匹配。写一个FTP客户端程序,把上面两个练习的脚本集成在一起。

17-10.递归和ZIP文件。这个练习与上面的第一个递归练习有些相似,只是不再直接把文件下载到本地文件系统,而是文件下载后压缩到一个ZIP(或TGZ,或BZ2)文件中。同样,你可以在之前脚本的基础上改,也可以重写一个。使用“-z”参数让用户可以自动地备份一个FTP站点。

17-11.集成。实现一个最终的,全功能的FTP应用程序,包含上面几个练习的所有功能。即,支持“-r” “-s”和“-z”参数。

NNTP

17-12.NNTP介绍。修改例17.2 (getLatestNNTP.py),让它显示第一封(而不是最后一封)有效文章的有意义的内容。

17-13.代码改进。修正getLatestNNTP.py的会输出3次引用问题,这是因为我们想输出Python交互解释的内容,而不是被3次引用的文本。用检查“>>>”后的代码是否为合法Python代码的方式来解决这个问题。如果合法,那就显示这一行数据,如果不合法,认为是引用文本,不显示。附加题:你的解决方案再解决这样一个小问题:我们没有去掉前导的空格,因为它可能是Python代码的缩进。如果真的是代码的缩进,就显示它,否则,认为它是一般的文本,先对字符串用Istrip()方法处理后再显示。

17-14.查找文章。写一个NNTP客户端程序,让用户能选择并登录感兴趣的新闻组。在登录成功后,提示用户输入一些关键字,使用这些关键字来查找文章的标题。把符合要求的文章列出来显示给用户。用户可以在列表中选择某一篇文章进行阅读,这时要能显示选定文章的内容。程序还要有简单的导航功能,如分页等。如果没有给出搜索关键字,则显示所有的文章。

17-15.搜索内容。修改上一题你的脚本,让脚本同时搜索主题和文章内容。允许关键字的“与”(AND)和“或”(OR)的操作。也要允许指定在标题和文章内容的“与”(AND)和“或”(OR)即,关键字要只在标题里出现,只在内容里出现或两者里面都要出现。

17-16.线索化的新闻阅读工具。把不同的回帖组织到一个“文章线索”中。也就是说,把相关的文章放在一起,与文章什么时候发的没有关系。同一个线索中的文章按时间顺序排列。用户可以:

(a)选择某一篇文章进行阅读,然后可以选择回到文章列表,顺序阅读当前线索的前一篇文章或是后一篇文章。

(b)允许回复线索,可以选择复制并引用之前文章,用跟贴的方式回复到整个新闻组。附加题:也允许私下用电子邮件进行回复。

(c)永久地删除线索,即后续的相关文章不会在文章列表中显示。要实现这个功能,你应该把要删除的文章的列表暂时记录下来。一个线索在几个月之后还没有人回复的话,你可以认为这个线索已经死了。

17-17.GUI新闻阅读工具。跟上面的FTP练习差不多,选择一个GUI工具包来实现一个完整的、独立的GUI新闻阅读工具。

17-18.重构。跟FTP的ftpmirror.py一样,NNTP也有一个示例脚本:Demo/scripts/newslist. py。运行它。这个脚本在很久之前就写好了,你可以做一些翻新工作。作为练习,你要用Python新版本的一些特性和你的Python开发技巧来重构这个脚本,让这个脚本运行得更快。你可以使用列表解析和生成器表达式,用更智能的字符串连接而不是调用不必要的函数等。

17-19.缓冲。如其作者所说,newslist.py的另一个问题是,“我应该把要忽略的空的新闻组的列表保存下来,在每次运行的时候检查一下是否有新的文章,但我真的抽不出时间”。你来实现这个功能。你可以直接修改它,也可以修改你之前的脚本。电子邮件

17-20.标识符。POP3的pass()方法用于在调用login()方法传了用户名之后传递密码。你能不能说出,为什么这个方法命名时要在后面加一个下划线,即“pass()”,而不是“pass()”?

17-21.IMAP。现在,你已经熟悉了POP是怎么工作的。这方面的经验对你写一个IMAP客户端程序也是有帮助的。研究一下IMAP协议的RFC文档,使用Python的imaplib模块来实现一个IMAP客户端程序。

下面的练习题跟本章(例17.3)中的myMail.py程序有关。

17-22.电子邮件头。在myMail.py的最后几行,比较了发送的信息体与接收到的电子邮件的信息体。写一段相似的代码,比较信息头。注意,要忽略新加入的头。

17-23.错误检查。加入SMTP和POP3的错误检查。

17-24.SMTP和IMAP。在简单的myMail.py中,加入IMAP的支持。附加题:支持两种邮件下载协议,让用户选择要使用哪一种协议。

17-25.撰写电子邮件。再次扩展你之前的程序,允许用户撰写和发送电子邮件。

17-26.电子邮件应用程序。再次扩展你的电子邮件应用程序,在其中加入更有用的邮箱管理功能。你的程序要能读出当前所有电子邮件的信息,并显示其主题。用户可以选择想要看的邮件。附加题:要能支持用外部程序查看附件。

17-27. GUI。给你的脚本加入GUI的功能,让它成为一个实用的完整的电子邮件应用程序。

17-28.垃圾邮件的特点。不请自来的垃圾邮件(spam)是当今的一大问题。所幸,针对这个问题有不少好的解决方案。我们不用你来重新发明轮子,我们想让你了解一些垃圾邮件的特点。

(a) “mbox”格式。在开始之前,我们要把你想处理的电子邮件信息转为一个公共的格式。

比如“mbox”格式。(如果你愿意,你也可以使用别的格式。)如果你已经有了一些mbox格式的消息,把它们合并到一个文件中。

(b)头。很多电子邮件的头上就看出有垃圾邮件的线索。(你可以用email包或自己解析头)。写一段代码来回答以下问题:

-发送这个消息的电子邮件客户端软件是什么?(检查X-Mailer头)

-报文ID (Message-ID头)的格式是否合法?

-From, Received和Return-Path头的域名是否不匹配?域名和IP地址是否不匹配?有没有X-Authentication-Warning头?如果有的话,内容是什么?

(c)信息服务器。一些服务器如WHOIS, SenderBase.org等可以根据IP地址或域名帮助你找到电子邮件来自何方。找到一些这样的服务,写一些代码来得到来源地的国别、城市、网络所有者的名字、联系方法等。

(d)关键字。垃圾邮件中,有一些字经常出现。你之前一定见过,它们是单个的字母,开头大写的随机字母等。把你常见的一些大量在垃圾邮件中出现的词汇放在一个列表中。把出现了这些词汇的邮件作为疑似垃圾邮件隔离。附加题:设计一种算法或加入一些关键字的变形来找出这些邮件。

(e)钓鱼。这些垃圾邮件总是想把他们伪装成来自大银行或某个知名的网站的合法的电子邮件。里面包含某种链接,引诱用户输入自己私密的或是敏感的信息,如登录用户名、密码和信用卡的卡号等。这些骗子往往做得足以以假乱真。不过,他们还是免不了要让用户登录到与他们声称的并不相符的网站。这里,就可能会透露出很多信息,如,看上去很乱七八糟的域名,只用了IP地址,或是32位整型形式而不是字节形式的IP地址等。写一段代码来判断一封看上去像正式交流的电子邮件是真的还是假的。

其他

可以在http://www.networksorcery.com/enp/topic/ipsuite.htm#Application%201ayer%20protocols找到包含本章中所列的那些协议在内的各种网际协议的列表。Python(当前)所支持的网际协议列表可以在http://docs.python.org/lib/internet.html找到。

17-29.开发其他因特网客户端程序。现在,你已经看到了4个Python开发因特网客户端程序的例子。选一种Python标准库中支持的其他协议,开发一个对应的客户端程序。

17-30.*开发一种新的因特网客户端程序。这个难度比较大:找到一个不常用的,或是还未成型的Python尚未支持的协议,实现它。如果做得好的话,你可以考虑提交一个PEP,把你的实现加入到以后版本Python的标准库中发布。