Foundations of Python Network Programming - 读书笔记系列(2) - Web Services

简介:

Web Client Access

HTTP(Hypertext Transfer Prototol)协议是如今使用最广的协议之一。Python中通常使用urllib2模块来实现HTTP协议。
urllib和urllib2的区别?urllib2更据扩展性,同时和urllib一样具备了基本的功能。而urllib提供了较多的一些实用的功能。

1. Fetching Web Pages

复制代码
import  sys, urllib2

req 
=  urllib2.Request(sys.argv[ 1 ])
fd 
=  urllib2.urlopen(req)
print   " Retrieved " , fd.geturl()
info 
=  fd.info()
for  key, value  in  info.items():
    
print   " %s = %s "   %  (key, value)
复制代码

urllib2.urlopen()返回的是一个File-like对象,因此可以调用read()方法,比如:
复制代码
import  sys, urllib2

req 
=  urllib2.Request(sys.argv[ 1 ])
fd 
=  urllib2.urlopen(req)
while   1 :
    data 
=  fd.read( 1024 )
    
if   not  len(data):
        
break
    sys.stdout.write(data)
复制代码

2. Authenticating

通常,某些网页需要HTTP安全性验证才能访问(SSL),比如需要提供用户名和密码的信息。如果我们没有提供不要的信息去访问一个需要安全性验证的网页,将会返回一个HTTP401(Authorization Required),urllib2模块能够处理这种情况,看下面的例子:
复制代码
import  sys, urllib2, getpass

class  TerminalPassword(urllib2.HTTPPasswordMgr):
    
def  find_user_password(self, realm, authuri):
        retval 
=  urllib2.HTTPPasswordMgr.find_user_password(self, realm,
                                                            authuri)
        
if  retval[0]  ==  None  and  retval[ 1 ==  None:
            
#  Did not find it in stored values; prompt user.
            sys.stdout.write( " Login required for %s at %s\n "   %  \
                             (realm, authuri))
            sys.stdout.write(
" Username:  " )
            username 
=  sys.stdin.readline().rstrip()
            password 
=  getpass.getpass().rstrip()
            
return  (username, password)
        
else :
            
return  retval

req 
=  urllib2.Request(sys.argv[ 1 ])
opener 
=  urllib2.build_opener(urllib2.HTTPBasicAuthHandler(TerminalPassword()))
fd 
=  opener.open(req)
print   " Retrieved " , fd.geturl()
info 
=  fd.info()
for  key, value  in  info.items():
    
print   " %s = %s "   %  (key, value)
复制代码

仔细分析一下上面的代码,第一步还是一样调用了Request()方法,第二步使用了urlib2.build_opener()方法创建一个opener,里面的参数是类似委托类型,当网页需要安全性验证时,HTTPBasicAuthHandler将会自动调用委托的方法TerminalPassword,而这个TerminalPassword是一个继承自urllib2.HTTPPasswordMgr的类,用于在需要用户名和密码时提供相应的信息。其实,在我们的第一个例子中(不需要安全性验证的例子),build_opener()在urlopen()的内部自动被调用了,传的参数为空,因为网页不需要安全性验证。

3. Submitting Form Data -- Get

提交表单数据其实有很多种,本书提到了是两种:Get和Post,其实还有比如:Put方式(不知道Python里有没有提供)。先来看Get方式,Get方式是直接把要提交的数据放在URL里的,每个参数之间用&号隔开。看下面的代码:
复制代码
import  sys, urllib2, urllib

def  addGETdata(url, data):
    
""" Adds data to url.  Data should be a list or tuple consisting of 2-item
    lists or tuples of the form: (key, value).

    Items that have no key should have key set to None.

    A given key may occur more than once.
    
"""
    
return  url  +   ' ? '   +  urllib.urlencode(data)

zipcode 
=  sys.argv[ 1 ]
url 
=  addGETdata( ' http://www.wunderground.com/cgi-bin/findweather/getForecast ' ,
                 [(
' query ' , zipcode)])
print   " Using URL " , url
req 
=  urllib2.Request(url)
fd 
=  urllib2.urlopen(req)
while   1 :
    data 
=  fd.read( 1024 )
    
if   not  len(data):
        
break
    sys.stdout.write(data)
复制代码

4. Submitting From Data -- Post

Post方式是把要提交的数据单独放在一个地方而不是简单的放在URL中,主要用于发送一些比较大的数据。使用起来其实也很简单,如下:
复制代码
import  sys, urllib2, urllib

zipcode 
=  sys.argv[ 1 ]
url 
=   ' http://www.wunderground.com/cgi-bin/findweather/getForecast '
data 
=  urllib.urlencode([( ' query ' , zipcode)])
req 
=  urllib2.Request(url)
fd 
=  urllib2.urlopen(req, data)
while   1 :
    data 
=  fd.read( 1024 )
    
if   not  len(data):
        
break
    sys.stdout.write(data)
复制代码
注意到,Get和Post方式都需要把要传输的数据encode,都是调用了urllib.urlencode()方法,其实这个方法只是将你要传输的数据的Key和Value用一些符号连接起来,比如连接成下面的样子:
username = abc & search = whoareyou
Get和Post使用起来的不同之处在于urllib2.urlopen()上,Post使用了两个参数。

5. Catching Connection Errors

连接一个地址时,假如主机不存在,域名错误等等,会返回一些错误的信息,比如:404(File Not Found)。而urllib2.URLError可以捕捉连接时的任何异常。然后,HTTP的一些异常信息通常伴随着一些描述性的文档,当我们只是要捕捉这样的异常,同时获取异常的内部信息时,可以使用urllib2.HTTPError来捕获,urllib2.HTTPError是urllib2.URLError的子类,它是一个file-like对象,因此可以直接用read()方法读取内部信息。下面的例子:
复制代码
import  sys, urllib2

req 
=  urllib2.Request(sys.argv[ 1 ])

try :
    fd 
=  urllib2.urlopen(req)
except  urllib2.HTTPError, e:
    
print   " Error retrieving data: " , e
    
print   " Server errror document follows:\n "
    
print  e.read()
    sys.exit(
1 )
except  urllib2.URLError, e:
    
print   " Error retrieving data: " , e
    sys.exit(
2 )

print   " Retrieved " , fd.geturl()
info 
=  fd.info()
for  key, value  in  info.items():
    
print   " %s = %s "   %  (key, value)
复制代码
假如出现HTTP Error,你将会输出如下信息:

6. Cathing Data Errors

前面是捕捉了连接时的异常,同样,在读数据或写数据时,也会发生异常。有两种情况:一是当使用read()时,连接出现异常(communication error),会抛出socket.error,这时我们捕获这个异常就可以了。二是读取的文件读到一半意外被中断,比如服务器的某个程序崩溃了,这时,连接会被正常的关闭,你接受不到任何异常的信息。这时,你就必须从header里找Content-Length,然后和自己接收的数据大小进行比较。(Content-Length在其他非HTTP协议中通常是没有的)
复制代码
import  sys, urllib2, socket

req 
=  urllib2.Request(sys.argv[ 1 ])

try :
    fd 
=  urllib2.urlopen(req)
except  urllib2.HTTPError, e:
    
print   " Error retrieving data: " , e
    
print   " Server errror document follows:\n "
    
print  e.read()
    sys.exit(
1 )
except  urllib2.URLError, e:
    
print   " Error retrieving data: " , e
    sys.exit(
2 )

print   " Retrieved " , fd.geturl()

bytesread 
=  0

while   1 :
    
try :
        data 
=  fd.read( 1024 )
    
except  socket.error, e:
        
print   " Error reading data: " , e
        sys.exit(
3 )

    
if   not  len(data):
        
break
    bytesread 
+=  len(data)
    sys.stdout.write(data)

if  fd.info().has_key( ' Content-Length ' and  \
   long(fd.info()[
' Content-Length ' ])  !=  long(bytesread):
    
print   " Expected a document of size %d, but read %d bytes "   %  \
          (long(fd.info()[
' Content-Length ' ]), bytesread)
    sys.exit(
4 )
复制代码
注意到上面我们使用的sys.exit(),几个地方使用了不同的参数:1,2,3,4,这些是退出代码,通常当退出代码是0时表示程序是正常退出的,其他的任何的都是不正常退出的。我们在上面使用了其他退出代码是为了能让调用我们脚本的程序更方便的得到我们的脚本退出的信息。
urllib2模块不仅仅支持HTTP协议,同样支持其他非HTTP协议,比如FTP。不同的是,比如FTP协议你不会在有header的信息,因此你当你调用info()函数时会出错的。不过通常情况下,使用urllib2来进行其他非HTTP协议也是非常方便的,基本上不需要再额外做什么,比如最前面第二个例子,我们讲传入的参数设置为FTP地址,同样使用。
复制代码
import  sys, urllib2

req 
=  urllib2.Request(sys.argv[ 1 ])
fd 
=  urllib2.urlopen(req)
while   1 :
    data 
=  fd.read( 1024 )
    
if   not  len(data):
        
break
    sys.stdout.write(data)
复制代码
运行如下:



本文转自CoderZh博客园博客,原文链接:http://www.cnblogs.com/coderzh/archive/2008/06/23/1228429.html,如需转载请自行联系原作者

目录
相关文章
|
22小时前
|
JavaScript 前端开发 UED
WebSocket在Python Web开发中的革新应用:解锁实时通信的新可能
在快速发展的Web应用领域中,实时通信已成为许多现代应用不可或缺的功能。传统的HTTP请求/响应模式在处理实时数据时显得力不从心,而WebSocket技术的出现,为Python Web开发带来了革命性的变化,它允许服务器与客户端之间建立持久的连接,从而实现了数据的即时传输与交换。本文将通过问题解答的形式,深入探讨WebSocket在Python Web开发中的革新应用及其实现方法。
7 3
|
4天前
|
SQL 安全 数据库
惊!Python Web安全黑洞大曝光:SQL注入、XSS、CSRF,你中招了吗?
在数字化时代,Web应用的安全性至关重要。许多Python开发者在追求功能时,常忽视SQL注入、XSS和CSRF等安全威胁。本文将深入剖析这些风险并提供最佳实践:使用参数化查询预防SQL注入;通过HTML转义阻止XSS攻击;在表单中加入CSRF令牌增强安全性。遵循这些方法,可有效提升Web应用的安全防护水平,保护用户数据与隐私。安全需持续关注与改进,每个细节都至关重要。
30 5
|
3天前
|
存储 JSON API
实战派教程!Python Web开发中RESTful API的设计哲学与实现技巧,一网打尽!
在数字化时代,Web API成为连接前后端及构建复杂应用的关键。RESTful API因简洁直观而广受欢迎。本文通过实战案例,介绍Python Web开发中的RESTful API设计哲学与技巧,包括使用Flask框架构建一个图书管理系统的API,涵盖资源定义、请求响应设计及实现示例。通过准确使用HTTP状态码、版本控制、错误处理及文档化等技巧,帮助你深入理解RESTful API的设计与实现。希望本文能助力你的API设计之旅。
16 3
|
4天前
|
中间件 API 开发者
深入理解Python Web框架:中间件的工作原理与应用策略
在Python Web开发中,中间件位于请求处理的关键位置,提供强大的扩展能力。本文通过问答形式,探讨中间件的工作原理、应用场景及实践策略,并以Flask和Django为例展示具体实现。中间件可以在请求到达视图前或响应返回后执行代码,实现日志记录、权限验证等功能。Flask通过装饰器模拟中间件行为,而Django则提供官方中间件系统,允许在不同阶段扩展功能。合理制定中间件策略能显著提升应用的灵活性和可扩展性。
13 4
|
4天前
|
JSON API 数据库
从零到英雄?一篇文章带你搞定Python Web开发中的RESTful API实现!
在Python的Web开发领域中,RESTful API是核心技能之一。本教程将从零开始,通过实战案例教你如何使用Flask框架搭建RESTful API。首先确保已安装Python和Flask,接着通过创建一个简单的用户管理系统,逐步实现用户信息的增删改查(CRUD)操作。我们将定义路由并处理HTTP请求,最终构建出功能完整的Web服务。无论是初学者还是有经验的开发者,都能从中受益,迈出成为Web开发高手的重要一步。
23 4
|
2天前
|
缓存 中间件 网络架构
Python Web开发实战:高效利用路由与中间件提升应用性能
在Python Web开发中,路由和中间件是构建高效、可扩展应用的核心组件。路由通过装饰器如`@app.route()`将HTTP请求映射到处理函数;中间件则在请求处理流程中插入自定义逻辑,如日志记录和验证。合理设计路由和中间件能显著提升应用性能和可维护性。本文以Flask为例,详细介绍如何优化路由、避免冲突、使用蓝图管理大型应用,并通过中间件实现缓存、请求验证及异常处理等功能,帮助你构建快速且健壮的Web应用。
8 1
|
2天前
|
开发框架 JSON 缓存
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
在数字化浪潮推动下,RESTful API成为Web开发中不可或缺的部分。本文详细介绍了在Python环境下如何设计并实现高效、可扩展的RESTful API,涵盖框架选择、资源定义、HTTP方法应用及响应格式设计等内容,并提供了基于Flask的示例代码。此外,还讨论了版本控制、文档化、安全性和性能优化等最佳实践,帮助开发者实现更流畅的数据交互体验。
13 1
|
3天前
|
前端开发 API Python
WebSocket技术详解:如何在Python Web应用中实现无缝实时通信
在Web开发的广阔领域中,实时通信已成为许多应用的核心需求。传统的HTTP请求-响应模型在实时性方面存在明显不足,而WebSocket作为一种在单个长连接上进行全双工通信的协议,为Web应用的实时通信提供了强有力的支持。本文将深入探讨WebSocket技术,并通过一个Python Web应用的案例分析,展示如何在Python中利用WebSocket实现无缝实时通信。
9 2
|
4天前
|
JSON API 开发者
惊!Python Web开发新纪元,RESTful API设计竟能如此性感撩人?
在这个Python Web开发的新纪元里,RESTful API的设计已经超越了简单的技术实现,成为了一种追求极致用户体验和开发者友好的艺术表达。通过优雅的URL设计、合理的HTTP状态码使用、清晰的错误处理、灵活的版本控制以及严格的安全性措施,我们能够让RESTful API变得更加“性感撩人”,为Web应用注入新的活力与魅力。
14 3
|
4天前
|
SQL 安全 Go
SQL注入不可怕,XSS也不难防!Python Web安全进阶教程,让你安心做开发!
在Web开发中,安全至关重要,尤其要警惕SQL注入和XSS攻击。SQL注入通过在数据库查询中插入恶意代码来窃取或篡改数据,而XSS攻击则通过注入恶意脚本来窃取用户敏感信息。本文将带你深入了解这两种威胁,并提供Python实战技巧,包括使用参数化查询和ORM框架防御SQL注入,以及利用模板引擎自动转义和内容安全策略(CSP)防范XSS攻击。通过掌握这些方法,你将能够更加自信地应对Web安全挑战,确保应用程序的安全性。
21 3