python基础教程_学习笔记24:网络编程、Python和万维网

网络编程

python是一个很强大的网络编程工具,首先,它有很多针对常见网络协议的库,在库顶部可以获得抽象层,这样可以集中精力在程序的逻辑处理上,而不是停留在网络实现的细节上;其次,python处理字节流的各种模式方面很擅长,因此可以轻松处理各种协议格式。

少数几个网络设计模块

socket模块

在网络编程中的一个基本组件就是套接字(socket)。套接字主要是两个程序之间“信息通道”。程序可能(通过网络连接)分布在不同的计算机上,通过套接字相互发送信息。在Python中的大多数的网络编程都隐藏了socket模块的基本细节,并且不直接和套接字交互。

套接字包括两个:服务器套接字和客户端套接字。

创建一个服务器套接字后,让它等待连接。这样它就在某个网络地址处(ip地址和一个端口号的组合)监听。

处理客户端套接字通常比处理服务器套接字容易,因为服务器必须准备随时处理客户端的连接,同时还要处理多个连接,而客户端只是简单的连接,完成事务,断开连接。

一个套接字就是一个socket模块中的socket类的实例。有三个参数:第一个是地址族(默认是socket.AF_INET),第二个参数是流(默认是socket.SOCK_STREAM,默认值)或数据报(socket.SOCK_DGRAM)套接字。第三个参数是使用的协议(默认是0,使用默认值即可)。对于一个普通的套接字,不需要提供任何参数。

服务器端套接字使用bind方法后,再调用listen方法监听这个给定地址。客户端套接字使用connect方法连接到服务器在connect方法中使用的地址与bind方法中的地址相同。在这种情况下,一个地址就是一个格式为(host,port)的元组,其中host是主机名,port是端口号。Listen方法只有一个参数,即服务器未处理的连接的长度。

服务器套接字开始监听后,它就可以接受客户端的连接。这个步骤使用accept方法来完成。这个方法会堵塞(等待)直到客户端连接,然后该方法就返回一个格式为(client,address)的元组。服务器能处理客户端到它满意的程度,然后调用一个accept方法开始等待下一个连接。这个过程通常都是在一个无限循环中实现的。

套接字有两个方法:send和rev,用于传输数据。可以使用字符串参数调用send以发送数据,用一个所需的(最大)字节数做参数调用recv来接收数据。如果不能确定使用哪个数字比较好,那么1024是个很好的选择。

小型服务器

import socket

s=socket.socket()

host=socket.gethostname()

port=1234

s.bind((host,port))

s.listen(5)

while True:

c,addr = s.accept()

print "Got connect from",addr

c.send(‘tkx for connecting‘)

c.close()

小型客户端

import socket

s=socket.socket()

host=socket.gethostname()

port=1234

s.connect((host,port))

print s.recv(1024)

urllib和urllib2模块

在能使用的各种网络工作库中,功能最强大的是urllib和urllib2。它们能让通过网络访问文件,就像那些文件存在于你电脑上一样。通过一个简单的函数调用,几乎可以把任何URL所指向的东西用作程序的输入。

这两个模块功能差不多,但urllib更好一些。如果只使用简单的下载,urllib就足够了。但如果需要使用HTTP验证或cookie或者要为自己的协议写扩展程序的话,urllib2是个好的选择。

打开远程文件

>>> from urllib import urlopen

>>> webpage=urlopen("http://blog.csdn.net/signjing")

Urlopen返回的类文件对象支持close、read、readline和readlines方法,当然也支持迭代。

获取远程文件

函数urlopen提供一个能从中读取数据的类文件对象。如果希望urllib为你下载文件并在本地文件存在一个文件的副本,那么可以使用urlretrieve。

Urlretrieve返回一个元组(filename,headers)而不是类文件对象,filename是本地文件的名字(由urllib自动创建),headers包含一些远程文件的信息。

>>> import urllib

>>> urllib.urlretrieve(‘http://www.baidu.com‘,‘d:\\baidu.html‘)

(‘d:\\baidu.html‘, <httplib.HTTPMessage instance at 0x02BFC788>)

如果没有指定文件名,文件会放在临时的位置,用open函数可以打开它。完成了对它的操作,就可以删除它以节省空间,要删除临时文件,可以用urlcleanup函数,不需要提供参数。

其它模块


模块


描述


asynchat


asyncore的增强版本


asyncore


异步套接字处理程序


cgi


基本的CGI支持


Cookie


Cookie对象操作,主要用于服务器


cookielib


客户端cookie支持


email


Email消息支持


ftplib


FTP客户端模块


gopherlib


gopher客户端模块


httplib


http客户端模块


imaplib


imap4客户端模块


mailbox


读取几种邮箱的格式


mailcap


通过mailcap文件访问MIME配置


mhlib


访问MH邮箱


nntplib


NNTP客户端模块


poplib


pop客户端模块


robotparser


支持解析web服务器的robot文件


SimpleXMLRPCServer


一个简单的xml-rpc服务器


smtpd


smtp服务器端模块


smtplib


smtp客户端模块


telnetlib


telnet客户端模块


urlparse


支持解释url


xmlrpclib


xml-rpc的客户端支持

SocketServer和它的朋友们

SocketServer模块是标准库中很多服务器框架的基础。

SocketServer包含了4个基本的类:针对TCP套接字流的TCPServer;针对UDP数据报套接字的UDPServer;以及针对性不强的UnixStreamServer和UnixDatagramServer。

多连接

到目前为止讨论的服务器解决方案都是同步的:即一次只能连接一个客户端并处理它的请求。

怎么样同时处理多个连接呢?

三种方法:分叉(forking)、线程(threading)以及异步I/O(asynchronous I/O)。

详略;

Twisted

Twisted是一个事件驱动的python网络框架,原来是为网络游戏开发的,现在被所有类型的网络软件使用。

下载并安装Twisted

编写Twisted服务器

这章之前编写的基本套接字服务器是显式的。其中的一些有很清楚的事件循环,用来查找新的连接和新数据,而基于SocketServer的服务器有一个隐式的循环,在循环中服务器查找连接并为每个连接创建一个处理程序,但处理程序在要读取数据时必须是显式的。

Twisted使用一个事件甚至多个基于事件的方法。要编写基本的服务器,就要实现处理比如新客户端连接、新数据到达以及一个客户端断开连接等事件的事件处理程序。具体的类能通过基本类建立更精炼的事件。

Python和万维网

万维网程序设计涉及的领域相当广,这里只选择三个主题:屏幕抓取、CGI和mod_python。

屏幕抓取

屏幕抓取是程序下载网页并且提取信息的过程。这个技术很有用,如果你想在你的程序中使用在线的网页中所包含的信息,就可以使用这个技术。如果所涉及的网页是动态的那就更有用了,也就是说网页是不停变化的。

Tidy和XHTML解析

python标准库中有很多支持结构化格式的库,例如html和xml。本节介绍一种用来处理xhtml的工具,xhtml是html最新的方言,是xml的一种形式。

对于包含正确而且有效的xhtml的网页而言,解析的工作很简单。问题在于旧版的html的方言较为随意,有些人甚至不关心这种随意的方言的限制。原因可能在于大部分网络浏览器都是很“宽容”的,并且会尽它们最大的努力来渲染最混乱且无意义的html。如果对于网页作者来说这是可以接受的,那么浏览器可能会很满意。而这却使屏幕抓取工作变得有点困难。

标准库中解析html的一般方法是基于事件的,所以需要编写像解析器一样顺序处理数据的事件处理程序。标准库模块sgmllib和htmllib可以用这种方式解析非常混乱的html,但如果希望提取基于文档结构的数据,那么在缺失标签的情况下可能要碰碰运气了。如果愿意的话,这么做当然也没问题,不过还有另外一种方法:Tidy。

tidy是什么

tidy是用来修复不规范且随意的HTML的工具。它能以相当智能的方法修复一般的错误,做那些你不愿意做的事情。它也是可设置的,也可以打开或关闭各种修改选项。

当然,tidy不能修复HTML文件的所有问题,但是它会确保文件的格式是正确的(也就是所有元素都正确嵌套),这样一来解析的时候就轻松多了。

获取tidy库

http://tidy.sourceforge.net/

http://www.berlios.de/

http://www.egenix.com/products/python/mxExperimental/mxTidy

但为什么用xhtml

XHTML和旧版本的HTML之间的最主要区别是XHTML对于显式关闭所有元素要求更加严格。所以在HTML中可能只用一个开始标签(<p>标签)结束一段然后开始下一段,而在XHTML中首先需要显式地关闭当前段落(用</p>标签)。这种行为让XHTML更容易解析,因为可以直接告诉程序什么时候进入或者离开各种元素。

XHTML的另外一个好处是它是XML的一种,所以可以对它使用XML的工具,如XPath。

解析这类从Tidy中获得的表现良好的XHTM方法是使用标准库模块(和类)HTMLParser。

使用htmlparser

使用HTMLParser的意思就是继承它,并且对handle_starttage或handle_data等事件处理方法进行覆盖。

如果要进行屏幕抓取,一般不需要实现所有的解析器回调,也可能不用创造整个文档的抽象表示法来查找自己需要的内容。如果只需要记录所需信息的最小部分,那么这就足够了。

Beautiful Soup

Beautiful Soup是个小模块,用来解析和检查经常在网上看到的那类乱七八糟而且不规范的HTML。

http://www.crummy.com/software/BeautifulSoup/

如果针对RSS feed进行分析,可以使用另外一个和Beautiful Soup相关的工具,叫做Scrape N Feed。

http://www.crummy.com/software/ScrapeNFeed/

使用CGI构建动态网页

CGI是网络服务器可以将查询(一般来说是通过Web表单)传递到专门的程序中并且在网页上显示结果的标准机制。它是创建万维网应用程序而不用编写特殊用途的应用服务器的简单方法。

python CGI程序设计的关键工具是cgi模块。cgitb是另外一个在CGI脚本开发过程中的有用模块。

使CGI脚本可通过网络访问(运行)之前,需要将它们放到网络服务器可以访问的地方,并且加入pound bang行,设置合适的文件许可。

第一步:准备网络服务器

假设可以访问网络服务器——换句话说可以在网络上放置文件。一般来说,可以把网页、图片等放在特殊的目录中。

CGI程序也应该放在通过网络可以访问的目录中。并且必须将它们标识为CGI脚本,这样网络服务器就不会将普通源代码作为网页处理。有两种方法可以实现这个功能:

将脚本放在叫做cgi-bin的子目录中;

把脚本文件扩展名改为.cgi;

具体的工作方式因服务器而异。

第二步:加入Pound Bang行

当把脚本放在正确位置(可能将其改为了特定的扩展名)后,需要在脚本的开始处增加pound bang行。没有这行的话,网络服务器就不知道如何执行脚本。一般来说,只要把下面这行加到脚本开始处就可以了:

#!/usr/bin/env python

注意,它一定要是第一行(之前没有空行)。如果不能正常功能,需要查看python可执行文件的确切位置,并使用全路径。如果还是不行,可以看看行结尾符是否是合法的,确保把文件存为了一个普通的unix风格的文本文件。

在windows系统中,可以使用python二进制版本的全路径,如:

#!c:\Python22\python.exe

第三步:设置文件许可

这里主要是指在unix或linux系统上需要给脚本文件以读取和执行的权限。

一般来说,不允许CGI脚本修改计算机上的任何文件。

CGI安全风险

使用CGI程序时也有安全问题存在。如果允许CGI脚本写服务器上的文件,那么除非非常小心地编写代码,否则可能会造成数据的损毁。同样,如果将用户提供的数据看作python代码或shell命令运行,也就承担了运行任意代码的风险,这是个很大(极其巨大)的安全问题。

简单的CGI脚本

#!/usr/bin/env python

print ‘Content-type:text/plain’

print

print ‘Hello,world!’

Content-type后面跟着一个冒号、一个空格和一个类型名text/plain。这表明页面是普通文本,如果页面是html,这一行应该是:

print ‘Content-type: text/html’

在所有的首部被打印后,打印一个空行表示文档即将开始。

使用cgitb调试

有时候编程的错误会让程序因为没有捕获的异常而以堆栈跟踪终止。当通过CGI运行程序时,这种情况很有可能会由服务器返回的无帮助错误信息。

cgitb是用于CGI回溯到模块,导入它并调用enable函数,就能得到包含出错信息的十分有用的网页。

注意,应在开发完成后关掉cgitb功能,因为回溯页不是为程序的一般用户准备的。

使用cgi模块

目前为止,程序只能产生输出,而不能接受任何形式的输入。输入是通过html表单提供给cgi脚本的键值对,或称字段。可以使用cgi模块的FieldStorage类从cgi脚本中获取这些字段。当创建FieldStorage实例时,它会从请求中获取输入变量,然后通过类字典接口将它们提供给程序。FieldStorage的值可以通过普通的键查找方式访问,但是因为一些技术原因,FieldStorage的元素并不是真正所要的值。

简单的表单

略;

更进一步:mod_python

安装mod_python

如果喜欢cgi,很可能会爱上mod_python。它是python网络服务器的扩展模块,可以从mod_python的网站上获取。它可以让python解释器直接成为apache的一部分,这样一来可以在程序中应用很酷的东西了。最重要的是它提供了python中编写apache处理程序的功能,和使用c语言不通,它是标准的。使用mod_python处理程序框架可以访问丰富的api,深入apache内核,等等。

除了基本功能外,还带有用于web开发的处理程序:

cgi处理程序

psp处理程序

发布处理程序

详略;

时间: 2024-10-13 17:10:24

python基础教程_学习笔记24:网络编程、Python和万维网的相关文章

python基础教程_学习笔记9:抽象

抽象 懒惰即美德. 抽象和结构 抽象可以节省大量工作,实际上它的作用还要更大,它是使得计算机程序可以让人读懂的关键. 创建函数 函数可以调用(可能包含参数,也就是放在圆括号中的值),它执行某种行为并且返回一个值.一般来说,内建的callable函数可以用来判断函数是否可调用: >>> import math >>> y=1 >>> x=math.sqrt >>> callable(x) True >>> callab

python基础教程_学习笔记14:标准库:一些最爱——re

标准库:一些最爱 re re模块包含对正则表达式的支持,因为曾经系统学习过正则表达式,所以基础内容略过,直接看python对于正则表达式的支持. 正则表达式的学习,见<Mastering Regular Expressions>(精通正则表达式) re模块的内容 最重要的一些函数 函数 描述 compile(pattern[,flags]) 根据包含正则表达式的字符串创建模式对象 search(pattern,string[,flags]) 在字符串中寻找模式 match(pattern,st

python基础教程_学习笔记2:序列-2

序列-2 通用序列操作 序列相加 通过加号对列表进行连接操作: 列表 >>> [1,3,4]+[2,5,8] [1, 3, 4, 2, 5, 8] 字符串 >>> '134'+'258' '134258' 元组 >>> (1,2,3)+(2,5,8) (1, 2, 3, 2, 5, 8) 元素数据类型不同的列表 >>> [[1,3],[3,9]]+[[2,2],'abc'] [[1, 3], [3, 9], [2, 2], 'abc'

python基础教程_学习笔记7:条件、循环、其它语句

条件.循环.其它语句 print和import 随着更加深入地学习python,可能会出现这种感觉:有些自以为已经掌握的知识点,还隐藏着一些让人惊讶的特性. 使用逗号输出 打印多个表达式,只要将这些表达式用逗号隔开即可: >>> print "age:",28 age: 28 参数之间都插入了一个空格符. 如果在结尾加上逗号,那么接下来的语句会与前一条语句在同一行打印: print "Hello,", print "World!"

python基础教程_学习笔记23:图形用户界面

图形用户界面 丰富的平台 在编写Python GUI程序前,需要决定使用哪个GUI平台. 简单来说,平台是图形组件的一个特定集合,可以通过叫做GUI工具包的给定Python模块进行访问. 工具包 描述 Tkinter 使用Tk平台.很容易得到.半标准. wxpython 基于wxWindows.跨平台越来越流行. PythonWin 只能在Windows上使用.使用了本机的Windows GUI功能. JavaSwing 只能用于Jython.使用本机的Java GUI. PyGTK 使用GTK

python基础教程_学习笔记3:元组

元组 元组不能修改:(可能你已经注意到了:字符串也不能修改.) 创建元组的语法很简单:如果用逗号分隔了一些值,那么你就自动创建了元组. >>> 1,3,'ab' (1, 3, 'ab') 元组也是(大部分时候是)通过圆括号括起来的. >>> (1,3,'13') (1, 3, '13') 空元组可以用没有内容的两个圆括号来表示. 如何实现包括一个值的元组呢? >>> (5) 5 >>> ('ab') 'ab' >>>

python基础教程_学习笔记10:异常

异常 什么是异常 Python用异常对象来表示异常情况.遇到错误后,会引发异常.如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(Traceback,一种错误信息)终止执行: >>> 1/0 Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> 1/0 ZeroDivisionError: integer division or modulo by

python基础教程_学习笔记6:字典

字典 映射(mapping),一种可通过名字引用值得数据结构. 字典是python中唯一内建的映射类型. 字典中的值没有特殊的顺序,但都存储在一个特定的键(key)里.键可以是数字.字符串甚至是元组. 字典的使用 某些情况下,字典比列表更加适用,比如: 表征游戏棋盘的状态,每个键都是由坐标值组成的元组: 存储文件修改数,用文件名作为键: 数字电话/地址簿: 假如有一个人名列表如下: >>>names=['Alice','Beth','Cecil','Dee-Dee','Earl'] 如果

python基础教程_学习笔记5:字符串

字符串 基本字符串操作 字符串也是序列,因此序列的基本操作(索引.分片.连接.乘法.长度.求最大值和最小值.成员资格)对字符串同样适用: 索引 >>> 'a_string'[0] 'a' 长度 >>> len('a_string') 8 求最大值 >>> max('a_string') 't' 求最小值 >>> min('a_string') '_' 乘法 >>> 'a_string'*2 'a_stringa_st