Python网络编程:从XML - RPC到Web开发
1. urllib包使用注意事项
高级用户可以对urllib包的行为进行各种自定义,如创建新的打开器、处理程序、请求和协议等,但此内容超出了这里的讨论范围,详细信息可查阅在线文档。此外,Python 2用户需要注意,广泛使用的
urllib.urlopen()
函数在Python 2.6中已被官方弃用,在Python 3中被移除。建议使用
urllib2.urlopen()
,它与这里描述的
urllib.request.urlopen()
功能相同。
2. xmlrpc包概述
xmlrpc包包含用于实现XML - RPC服务器和客户端的模块。XML - RPC是一种远程过程调用机制,使用XML进行数据编码,HTTP作为传输机制。其底层协议并非Python专用,因此使用这些模块的程序可以与其他语言编写的程序进行交互。更多关于XML - RPC的信息可在http://www.xmlrpc.com获取。
2.1 xmlrpc.client (xmlrpclib)
该模块用于编写XML - RPC客户端,在Python 2中称为
xmlrpclib
。要作为客户端运行,需创建
ServerProxy
实例:
ServerProxy(uri [, transport [, encoding [, verbose [, allow_none [, use_datetime]]]])
参数说明如下:
-
uri
:远程XML - RPC服务器的位置,例如
"http://www.foo.com/RPC2"
。必要时可添加基本认证信息,格式为
"http://user:pass@host:port/path"
。
-
transport
:用于创建内部传输对象的工厂函数,通常无需提供。
-
encoding
:编码,默认为UTF - 8。
-
verbose
:若为
True
,显示调试信息。
-
allow_none
:若为
True
,允许将
None
值发送到远程服务器,默认禁用。
-
use_datetime
:布尔标志,若为
True
,使用
datetime
模块表示日期和时间,默认
False
。
ServerProxy
实例可透明地访问远程服务器上的所有方法,示例代码如下:
>>> s = ServerProxy("http://www.xmlrpc.com/RPC2")
>>> s.currentTime.getCurrentTime()
<DateTime u'20051102T20:08:24' at 2c77d8>
>>>
XML - RPC协议支持的参数类型和返回值有限,具体对应关系如下表:
| XML - RPC Type | Python Equivalent |
| — | — |
| boolean | True and False |
| integer | int |
| float | float |
| string | string or unicode (must only contain characters valid in XML) |
| array | Any sequence containing valid XML - RPC types |
| structure | Dictionary containing string keys and values of valid types |
| dates | Date and time (xmlrpc.client.DateTime) |
| binary | Binary data (xmlrpc.client.Binary) |
当接收到日期时,存储在
xmlrpc.client.DateTime
实例
d
中,可使用
d.timetuple()
将其转换为与
time
模块兼容的时间元组。接收到二进制数据时,存储在
xmlrpc.client.Binary
实例
b
中,使用
b.data
提取数据。
若远程XML - RPC服务器支持自省,可使用以下方法:
-
s.system.listMethods()
:返回服务器提供的所有方法的字符串列表。
-
s.methodSignatures(name)
:返回指定方法的可能调用签名列表。
-
s.methodHelp(name)
:返回指定方法的文档字符串。
xmlrpclib
模块还提供了以下实用函数:
-
boolean(value)
:从值创建XML - RPC布尔对象。
-
Binary(data)
:创建包含二进制数据的XML - RPC对象。
-
DateTime(daytime)
:创建包含日期的XML - RPC对象。
-
dumps(params [, methodname [, methodresponse [, encoding [, allow_none]]]])
:将参数转换为XML - RPC请求或响应。
-
loads(data)
:将包含XML - RPC请求或响应的数据转换为元组
(params, methodname)
。
-
MultiCall(server)
:创建
MultiCall
对象,允许将多个XML - RPC请求打包为单个请求发送,示例代码如下:
multi = MultiCall(server)
multi.foo(4,6,7) # Remote method foo
multi.bar("hello world") # Remote method bar
multi.spam() # Remote method spam
# Now, actually send the XML - RPC request and get return results
foo_result, bar_result, spam_result = multi()
2.2 异常处理
xmlrpc.client
中定义了以下异常:
-
Fault
:表示XML - RPC故障,包含
faultCode
和
faultString
属性。
-
ProtocolError
:表示底层网络问题,包含
url
、
errcode
、
errmsg
和
headers
属性。
2.3 xmlrpc.server (SimpleXMLRPCServer, DocXMLRPCServer)
该模块包含用于实现不同类型XML - RPC服务器的类。在Python 2中,此功能分布在
SimpleXMLRPCServer
和
DocXMLRPCServer
两个模块中。
2.3.1 服务器创建
-
SimpleXMLRPCServer(addr [, requestHandler [, logRequests]]):创建一个监听指定套接字地址的XML - RPC服务器。 -
DocXMLRPCServer(addr [, requestHandler [, logRequest]):创建一个可响应HTTP GET请求的文档化XML - RPC服务器。
2.3.2 服务器方法
SimpleXMLRPCServer
或
DocXMLRPCServer
实例具有以下方法:
-
s.register_function(func [, name])
:注册新函数。
-
s.register_instance(instance [, allow_dotted_names])
:注册对象以解析未注册的方法名。
-
s.register_introspection_functions()
:添加XML - RPC自省函数。
-
s.register_multicall_functions()
:添加XML - RPC多调用函数支持。
DocXMLRPCServer
实例还提供以下方法:
-
s.set_server_title(server_title)
:设置服务器在HTML文档中的标题。
-
s.set_server_name(server_name)
:设置服务器在HTML文档中的名称。
-
s.set_server_documentation(server_documentation)
:添加描述性段落。
2.3.3 CGI脚本支持
XML - RPC服务器也可在CGI脚本中运行,使用以下类:
-
CGIXMLRPCRequestHandler([allow_none [, encoding]])
-
DocCGIXMLRPCRequestHandler()
这两个类的实例除了具有普通XML - RPC服务器的注册方法外,还定义了
c.handle_request([request_text])
方法来处理XML - RPC请求。
2.4 示例代码
以下是一个简单的独立服务器示例:
try:
from xmlrpc.server import SimpleXMLRPCServer # Python 3
except ImportError:
from SimpleXMLRPCServer import SimpleXMLRPCServer # Python 2
import math
def add(x,y):
"Adds two numbers"
return x+y
s = SimpleXMLRPCServer(('',8080))
s.register_function(add)
s.register_instance(math)
s.register_introspection_functions()
s.serve_forever()
以下是相同功能的CGI脚本实现:
try:
from xmlrpc.server import CGIXMLRPCRequestHandler # Python 3
except ImportError:
from SimpleXMLRPCServer import CGIXMLRPCRequestHandler # Python 2
import math
def add(x,y):
"Adds two numbers"
return x+y
s = CGIXMLRPCRequestHandler()
s.register_function(add)
s.register_instance(math)
s.register_introspection_functions()
s.handle_request()
从其他Python程序访问XML - RPC函数的示例如下:
>>> from xmlrpc.client import ServerProxy
>>> s = ServerProxy("http://localhost:8080")
>>> s.add(3,5)
8
>>> s.system.listMethods()
['acos', 'add', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'exp',
'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log', 'log10', 'modf',
'pow', 'radians', 'sin', 'sinh', 'sqrt', 'system.listMethods',
'system.methodHelp', 'system.methodSignature', 'tan', 'tanh']
>>> s.tan(4.5)
4.6373320545511847
>>>
2.5 高级服务器定制
XML - RPC服务器模块适用于基本的分布式计算,但存在安全问题,如默认开放服务、无请求数据大小限制等。可通过自定义服务器类或请求处理程序来解决这些问题,例如限制请求大小的示例代码如下:
try:
from xmlrpc.server import (SimpleXMLRPCServer,
SimpleXMLRPCRequestHandler)
except ImportError:
from SimpleXMLRPCServer import (SimpleXMLRPCServer,
SimpleXMLRPCRequestHandler)
class MaxSizeXMLRPCHandler(SimpleXMLRPCRequestHandler):
MAXSIZE = 1024*1024 # 1MB
def do_POST(self):
size = int(self.headers.get('content-length',0))
if size >= self.MAXSIZE:
self.send_error(400,"Bad request")
else:
SimpleXMLRPCRequestHandler.do_POST(self)
s = SimpleXMLRPCServer(('',8080),MaxSizeXMLRPCHandler)
3. Web编程
Python在网站建设中广泛应用,主要有以下几种角色:
3.1 生成静态HTML页面
Python脚本可用于生成静态HTML页面,主要涉及文件处理和文本处理。
3.2 生成动态内容
3.2.1 表单处理
网站可使用Python脚本动态处理特定请求,例如HTML表单:
<FORM ACTION='/cgi-bin/subscribe.py' METHOD='GET'>
Your name : <INPUT type='Text' name='name' size='30'>
Your email address: <INPUT type='Text' name='email' size='30'>
<INPUT type='Submit' name='submit-button' value='Subscribe'>
</FORM>
表单提交时,将执行
subscribe.py
脚本。
3.2.2 AJAX应用
AJAX(Asynchronous Javascript and XML)可使JavaScript事件处理程序与页面上的HTML元素关联。例如,鼠标悬停时发送HTTP请求到服务器,服务器可能返回纯文本、XML、JSON等格式的数据。以下是一个实现悬停弹出窗口的HTML示例:
<html>
<head>
<title>ACME Officials Quiet After Corruption Probe</title>
<style type="text/css">
.popup { border-bottom:1px dashed green; }
.popup:hover { background-color: #c0c0ff; }
</style>
</head>
<body>
<span id="popupbox"
style="visibility:hidden; position:absolute; background-color:
#ffffff;">
<span id="popupcontent"></span>
</span>
<script>
/* Get a reference to the popup box element */
var popup = document.getElementById("popupbox");
var popupcontent = document.getElementById("popupcontent");
/* Get pop-up data from the server and display when received */
function ShowPopup(hoveritem,name) {
var request = new XMLHttpRequest();
request.open("GET","cgi-bin/popupdata.py?name="+name, true);
request.onreadystatechange = function() {
var done = 4, ok = 200;
if (request.readyState == done && request.status == ok) {
if (request.responseText) {
popupcontent.innerHTML = request.responseText;
popup.style.left = hoveritem.offsetLeft+10;
popup.style.top = hoveritem.offsetTop+20;
popup.style.visibility = "Visible";
}
}
};
request.send();
}
/* Hide the popup box */
function HidePopup() {
popup.style.visibility = "Hidden";
}
</script>
<h3>ACME Officials Quiet After Corruption Probe</h3>
<p>
Today, shares of ACME corporation
(<span class="popup" onMouseOver="ShowPopup(this,'ACME');"
onMouseOut="HidePopup();">ACME</span>)
plummetted by more than 75% after federal investigators revealed that
the board of directors is the target of a corruption probe involving
the Governor, state lottery officials, and the archbishop.
</p>
</body>
</html>
在这个示例中,
ShowPopup()
函数向服务器上的
popupdata.py
脚本发起请求,脚本返回的HTML片段将显示在弹出窗口中。
3.3 基于Python框架运行整个网站
Python有众多的Web编程框架,可用于控制整个网站的运行。更多信息可参考http://wiki.python.org/moin/WebFrameworks。
4. 总结与拓展
4.1 技术点回顾
在前面的内容中,我们详细介绍了 Python 在网络编程中的多个方面,包括
urllib
包的使用注意事项、
xmlrpc
包的客户端与服务器实现,以及 Python 在 Web 编程中的不同应用场景。下面通过一个表格来总结这些关键技术点:
| 技术领域 | 关键内容 |
| — | — |
|
urllib
包 | 高级用户可自定义行为;Python 2 中
urllib.urlopen()
被弃用,建议使用
urllib2.urlopen()
|
|
xmlrpc
包 - 客户端 |
ServerProxy
用于访问远程服务器方法;支持有限的参数和返回值类型;提供自省方法和实用函数;支持多调用请求 |
|
xmlrpc
包 - 服务器 | 包含
SimpleXMLRPCServer
和
DocXMLRPCServer
类;支持函数和对象注册;可在 CGI 脚本中运行;可进行高级定制 |
| Web 编程 - 静态页面生成 | Python 脚本用于生成静态 HTML 页面,涉及文件和文本处理 |
| Web 编程 - 动态内容生成 | 表单处理:通过 HTML 表单触发 Python 脚本;AJAX 应用:JavaScript 与 Python 脚本交互实现动态效果 |
| Web 编程 - 框架应用 | Python 有众多 Web 编程框架,可控制整个网站运行 |
4.2 技术拓展与应用场景
4.2.1 XML - RPC 的拓展应用
XML - RPC 作为一种远程过程调用机制,在分布式系统中有着广泛的应用。例如,在企业级应用中,不同部门的系统可能运行在不同的服务器上,通过 XML - RPC 可以实现这些系统之间的通信和数据共享。以下是一个简单的 mermaid 流程图,展示了 XML - RPC 在分布式系统中的应用流程:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([客户端程序]):::startend --> B(创建 ServerProxy 实例):::process
B --> C(调用远程服务器方法):::process
C --> D{服务器处理请求}:::decision
D -->|成功| E(返回结果给客户端):::process
D -->|失败| F(抛出异常):::process
E --> G(客户端接收并处理结果):::process
F --> H(客户端捕获并处理异常):::process
4.2.2 Web 编程的拓展应用
在 Web 编程中,Python 的应用场景不断拓展。除了前面提到的静态页面生成、表单处理和 AJAX 应用外,还可以结合数据库实现数据的持久化存储和查询。例如,在一个电商网站中,可以使用 Python 脚本处理用户的订单信息,并将这些信息存储到数据库中。以下是一个简单的步骤列表,展示了如何实现这个功能:
1.
数据库连接
:使用 Python 的数据库连接库(如
sqlite3
、
mysql - connector - python
等)连接到数据库。
2.
订单信息处理
:在 Python 脚本中接收用户提交的订单信息,进行必要的验证和处理。
3.
数据插入
:将处理后的订单信息插入到数据库的相应表中。
4.
返回结果
:向用户返回订单处理结果,如订单号、支付信息等。
4.3 代码示例总结
为了方便大家回顾和使用,下面将前面提到的关键代码示例进行总结:
4.3.1 XML - RPC 服务器示例
try:
from xmlrpc.server import SimpleXMLRPCServer # Python 3
except ImportError:
from SimpleXMLRPCServer import SimpleXMLRPCServer # Python 2
import math
def add(x,y):
"Adds two numbers"
return x+y
s = SimpleXMLRPCServer(('',8080))
s.register_function(add)
s.register_instance(math)
s.register_introspection_functions()
s.serve_forever()
4.3.2 XML - RPC 客户端示例
from xmlrpc.client import ServerProxy
s = ServerProxy("http://localhost:8080")
print(s.add(3,5))
print(s.system.listMethods())
print(s.tan(4.5))
4.3.3 Web 编程 - 表单处理示例
<FORM ACTION='/cgi-bin/subscribe.py' METHOD='GET'>
Your name : <INPUT type='Text' name='name' size='30'>
Your email address: <INPUT type='Text' name='email' size='30'>
<INPUT type='Submit' name='submit-button' value='Subscribe'>
</FORM>
4.3.4 Web 编程 - AJAX 应用示例
<html>
<head>
<title>ACME Officials Quiet After Corruption Probe</title>
<style type="text/css">
.popup { border-bottom:1px dashed green; }
.popup:hover { background-color: #c0c0ff; }
</style>
</head>
<body>
<span id="popupbox"
style="visibility:hidden; position:absolute; background-color:
#ffffff;">
<span id="popupcontent"></span>
</span>
<script>
/* Get a reference to the popup box element */
var popup = document.getElementById("popupbox");
var popupcontent = document.getElementById("popupcontent");
/* Get pop-up data from the server and display when received */
function ShowPopup(hoveritem,name) {
var request = new XMLHttpRequest();
request.open("GET","cgi-bin/popupdata.py?name="+name, true);
request.onreadystatechange = function() {
var done = 4, ok = 200;
if (request.readyState == done && request.status == ok) {
if (request.responseText) {
popupcontent.innerHTML = request.responseText;
popup.style.left = hoveritem.offsetLeft+10;
popup.style.top = hoveritem.offsetTop+20;
popup.style.visibility = "Visible";
}
}
};
request.send();
}
/* Hide the popup box */
function HidePopup() {
popup.style.visibility = "Hidden";
}
</script>
<h3>ACME Officials Quiet After Corruption Probe</h3>
<p>
Today, shares of ACME corporation
(<span class="popup" onMouseOver="ShowPopup(this,'ACME');"
onMouseOut="HidePopup();">ACME</span>)
plummetted by more than 75% after federal investigators revealed that
the board of directors is the target of a corruption probe involving
the Governor, state lottery officials, and the archbishop.
</p>
</body>
</html>
4.4 未来展望
随着互联网技术的不断发展,Python 在网络编程领域的应用前景将更加广阔。在 XML - RPC 方面,可能会有更多的安全机制和性能优化方案出现,以满足企业级应用的需求。在 Web 编程方面,随着前端技术的不断进步,Python 与 JavaScript 等前端技术的结合将更加紧密,为用户带来更加丰富和流畅的 Web 体验。同时,Python 的 Web 编程框架也将不断发展和完善,为开发者提供更加便捷和高效的开发工具。
总之,掌握 Python 在网络编程中的这些技术,将有助于开发者更好地应对各种网络应用开发的挑战,为互联网的发展贡献自己的力量。
超级会员免费看
6668

被折叠的 条评论
为什么被折叠?



