Chinaunix首页 | 论坛 | 博客
  • 博客访问: 46127
  • 博文数量: 9
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 100
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-12 17:58
个人简介

熬着熬着,让时间熬成想要的那个自己,一个美丽的人。

文章分类

全部博文(9)

文章存档

2016年(1)

2014年(7)

2013年(1)

分类: Python/Ruby

2014-01-09 18:08:48


这章节将会谈论下Twisted Web中的HTTP client,从一次性应用程序的快速web资源检索到Agent API开发的弹性web client

基本HTTP资源检索

Twisted有几个高层工具类进行快速一次性资源检索。

输出一个web资源

Twisted.web.client.getPage异步地检索一个给定URL的资源。它返回一个Deferred,触发callback回调一个字符串资源。Example 5-1 强调了getPage的应用,检索并打印出用户提供的URL的资源。

除了名字,getPage能生成任何HTTP请求类型。用getPage产生一个HTTPPOST请求,提供方法和前数据关键词参数:比如,getPagesys.argv[1], method=POST, postdata=My test data)

getPage也提供了运用cookies信息记录后重定向,改变请求的用户代理。

下载一个Web 资源

Twisted.web.client.downloadPage 异步的下载给定的URL的资源到一个特定的文件。Example 5-2 强调了getPage的应用。

我们可以如下测试:

python download_resource.py 

会把Google的主页保存到文件google.html里面

Agent

getPagedownloadPage对获得较小的工作量来说还蛮适合,但是对主要的Twisted HTTP client API来说,还是得需要Agent,因为需要弹性可扩展的来支持一个广分布的RFC-compliant 行为。

请求Agent资源

Example 5-3 运用Agent API实现了跟Example5-1 中的print_resource.py 一样的功能。

Agent版本需要更多一点的工作量,但是它具有多用途的。我们来分解一下触发步骤:

1. 初始化一个twiste.web.client.Agent实例。因为agent处理连接环节,必须跟reactor一起初始化。

2. 运用agent的请求方法生成一个HTTP请求,至少需要HTTP方法和URL两个参数。如果成功agent.request会返回一个Deferred来触发一个封装了对请求予以回应的Response对象。

3. 注册一个有agent.request返回的Deferred的回调来处理Response主体,等response.deliverBody可用时。因为回应是通过成块在网络传输,我们需要Protocol来处理接收到的数据并在主体已经完全传输完后通知我们。

为打成目标,我们创建了一个Protocol的子类并命名为ResourcePrinter,跟我们第二章构建基本的TCP serverclient一样。不同之处在于我们想要在ResourcePrinter之外还能继续处理事件。通往外部的连接会是一个Deferred并在初始化时被传给ResourcePrinter实例,在连接中断时触发。这个DeferredprintResource创建并返回,因此更多的回调能够被记录进行额外的处理。伴随着回应主体块到达,reactor唤醒dataReceived,我们输出数据到屏幕。Reactor触发了connectionLost,我们就触发Deferred

4. 一旦连接终止,reactor就停止。为达到这个目的,我们注册了一个Deferred的停止函数来回调,由connectionLost来触发,由printResource来返回。重回addBoth注册的同一个函数给callbackerrback链,因此reactor不管下载是否成功都会停止。

5. 最后,运行reactor来关闭HTTP请求。

运行这个例子,python agent_print_resource.py  处理结果跟Example5-1一样。

检索响应元数据

Agent支持所有HTTP方法和任意的HTTP首部。Example 5-4 强调了HTTP 首部请求的功能。

Deferred中的Response对象由agent.request返回,包含大量有用HTTP响应元数据,包括HTTP状态码,HTTP版本以及首部。

Example5-4也强调了抽象信息。

用一个URL测试这个脚本:python print_metadata.py 

结果:

  HTTP version: ('HTTP', 1, 1)

  Status code: 302

  Status phrase: Found

  Response headers:

  Alternate-Protocol ['80:quic']

  Content-Length ['376']

  X-Xss-Protection ['1; mode=block']

  Set-Cookie                                                                                          ['PREF=ID=879d0e073388fc22:FF=0:NW=1:TM=1389252277:LM=1389252277:S=K3ZbvVInZeLAdlWV; expires=Sat, 09-Jan-2016 07:24:37 GMT; path=/; domain=.google.com']

  Server ['gws']

  Location ['']

Cache-Control ['private']

Date ['Thu, 09 Jan 2014 07:24:37 GMT']

X-Frame-Options ['SAMEORIGIN']

Content-Type ['text/html; charset=UTF-8']

Agent提交数据

Agent提交HTTP数据,我们需要构建一个生产商来创建IBodyProducer接口,在Agent需要的时候产生POST 数据。

注:即使进程以不同的速率产生并消耗,生产者/消费者设计模式设施就有可能大量以一种方式流向内存和cpu效率。 你可以参阅跟多关于Twisted的生产/消耗API

IBodyProducer接口是由Twistedzope.interface.implements实施,必须实现下面的几个方法,必须一个长度属性来跟踪生产商最终会产生的数据长度:

l startProducing

l stopProducing

l pauseProducing

l resumeProducing

比如,我们可以构建一个简单的StringProducer,当startProducing被触发的时候输出POST数据给等待的消耗者。StringProducer作为bodyProducer的参数被传给agent.request

测试这个例子我们需要用一个URL接收POST请求。不是一个好的测试例子,因为运行: python post_data.py  'Hello,worl!'

结果如下:

The request method POST is inappropriate for the URL /.  Thats all we know.

通过这个例子可知,能够简单的给一个基本的web server来提交数据是很有用的。当然,我们前面的章节可以修改Twisted web server

Python test_server.py 会启动web sever,监听8000端口。运行着server,我们可以从客户端测试了:python post_data.py 'Hello,world!'

结果:!dlrow,olleH

其他练习和下一步计划:

这个章节主要介绍了Twisted HTTP的客户端。高层的API getPagehe downloadPage能迅速简易检索资源。Agent是一个弹性可扩展的web client

Twisted Web Client HOWTO详细介绍了Agent API,包括处理代理和cookies信息记录程序。

Twisted Web examples目录有大量HTTP client的例子。

阅读(947) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~