能做到什么?
1. 使用URL对远程Web Server读取文件。
2. 对Web Serve利用POST 方式送出form request。
3. 对远程Webserver最近更新的文件作更新动作。
4. 解析HTML 文件,取得其中的「连结」与一些需要的数据。
5. 将HTML转成纯文本文件或Postscript档案。
6. 处理cookies,HTTP redirects, proxy servers, and HTTP user authentication.这些特殊事件。
重要特性:
1.包含许多可重复使用的组件,可独立运作或相互配合使用.
提供一个HTTP-style沟通的Object Oriented模型。支援 http, https, gopher, ftp, news, file, and mailto resources.
2.提供完整的OO接口。
3.支持基本的编码与认证功能
4.支持重新导向处理。
5.可以透过代理服务器(Proxy server)
6.可以透过robots.txt建构robots。有点类似网络上的爬虫程序。
7.实作HTTP的content negotiation algorithm 可以与CGI程序作界接。
8.支援 HTTP cookies.
8.有一个简单的指令格式应用程序: lwp-request.
安装时,要求先要安装的modules:
URI URL parsing and manipulation
Net::FTP to support ftp:// URLs
MIME::Base64 to support HTTP Basic authentication
Digest::MD5 to support HTTP Digest authentication
HTML::HeadParser for finding the <BASE> tag in HTML headers
(实际上更多,因为要安装上述module可能还要先安装其它modules)
#–比较建议这种方式安装,但是如果不能对外连结,只好跟我一样慢慢抓modules,一个一个安装
用CPAN方法安装:
#perl -MCPAN -e ‘install Bundle::LWP’
除了上面的模块外,另外还要安装
#perl -MCPAN -e ‘install HTML::Parser’ -e ‘install HTML::Formatter’
如果不用CPAN方式安装:
HTML-Parser HTML Parser
HTML-Tree HTML syntax-tree generation
Font-AFM Postscript font metrics
HTML-Format HTML Formatting
一定要要下载并安装上述modules..
如果要使用HTTPS必须要安装IO ::Socket ::SSL and OpenSSL library(http://www.openssl.org)
安装完LWP后,会帮你安装四个scripts
lwp-request 取得url并显示出来
lwp-download 下载文件到硬盘,适合大档案使用。
lwp-mirror 与远程的服务器的文件作镜射动作,只更新最近有被改变的文件。
Lwp-rget 递回的取得整个档案架构
LWP基础程序:
#!/usr/bin/perl
# file get_url.pl
#–开启语法检查并使用LWP modules
use strict;
use LWP;
#–取得URL
my $url = shift;
#–建立LWP ::UserAgent 与HTTP ::Request 物件,
#–其中Request对象将$url传进去
my $agent=LWP::UserAgent->new();
my $request = HTTP::Request->new(GET=>$url);
#–透过UserAgent的request method将Request送出
my $response= $agent->request($request);
#–检查是否有error发生
$response->is_success or die “$url: “,$response->message,”\n”;
#–显示responser的内容
print $response->content;
其中HTTP ::Request Object可以很简单的只有一个URL也可以很复杂的包含cookies、authentication information与CGI script所需要的arguments。
HTTP ::Response对象,主要将Server回传的结果打包起来,其包含执行结果状态的信息加上文件内容。
LWP ::UserAgent 为一个介于Client与Server中间的媒介,负责传送Request至Server,并将Server的回传值解析后存入HTTP ::Response Object中。
另外也可以使用LWP ::Simple的Modules也可以作相同的事情。
# !/usr/bin/perl
# file simple_get.pl
use LWP ::Simple ;
my $url = shift;
#–如果正常会显示内容,否则
getprint($url);
LWP中最重要的三个对象:HTTP::Request、HTTP::Response、LWP::UserAgent。
以下分别针对这三个modules作说明。
LWP Modules里面Modules间的概观:
LWP::MemberMixin — Access to member variables of Perl5 classes
LWP::UserAgent — WWW user agent class
LWP::RobotUA — When developing a robot applications
LWP::Protocol — Interface to various protocol schemes
LWP::Protocol::http — http:// access
LWP::Protocol::file — file:// access
LWP::Protocol::ftp — ftp:// access
…
LWP::Authen::Basic — Handle 401 and 407 responses
LWP::Authen::Digest
HTTP::Headers — MIME/RFC822 style header (used by HTTP::Message)
HTTP::Message — HTTP style message
HTTP::Request — HTTP request
HTTP::Response — HTTP response
HTTP::Daemon — A HTTP server class
WWW::RobotRules — Parse robots.txt files
WWW::RobotRules::AnyDBM_File — Persistent RobotRules
Net::HTTP — Low level HTTP client
在Web 服务的典型中,所有Client与Server的交互作用分为Client的request与Server的reponse
HTTP::Request:
Client的request包含URL与所使用的method。事实上HTTP::Rquset使用的是URI(Uniform Resource Identifier)包含了通讯协议与连结的服务器。
通讯协议:
HTTP (http://www.abc:port/path/)、FTP(ftp://ftpname:port/path)、GOPHER(gopher:: //gophername:port/path)、SMTP(mailto:user@mailserver)、NEWS(news:message- id)
这个modules支持的方法:
GET 取得URL的文件(web page)
PUT 替代或建立URL上的文件(ftp)
POST 送出事先准备好的Form至Server处。
DELETE 删除URL上的文件(FTP Server)
HEAD 取得URL的信息
HTTP协议包含其它信息:(RFC 822-like 字段)这里只有部分:
Accept 指出client准备送出的MIME型态
User-agent Client软件的名称与版本
Content-type Request的文件型态
PUT与POST method:Request可以包含文件内容(content data)。
PUT:包含要上传的到URL的文件内容。
POST:包含已经填好的要送出至CGI Script的Form。
LWP使用HTTP::Request表示所有经由LWP所发送出去的的Request,不是只有HTTP也可以包含FTP、NNTP、SMTP等协议。
Method的说明:
$request=HTTP::Request->new($method,$url[,$header[,$content]])
建构HTTP::Request物件。最少要两个自变量($method与$url)。$URL可以是URI对象。Header与content可以对象建立后再补数据。
$request->header($field1=>$val1,$feild2=>$val2..) 设定$field数值。
@values=$request->header($field):取得某个field里面的所有数值。可以是list也可以是scalar variable用”,”分隔的Variable。
$request->push_header($filed=>$value)
将$field与$value加入在header最后面
$request->remove_header(@fields)
删掉特定的fields
$request->scan(\?)
对每个HTTP header作迭代每个element都丢入? function中,主要传入field数值与value数值。
从HTTP::Header modules中继承来的method..
$request->date():设定时间
$request->expires():设定过期时间
$request->last_modified():设定resources最后修改时间
$request->if_modified_since():检查是否从$date后有被修正过。
$request->content_type():设定讯息内容的形式
$request->content_length():设定讯息的长度
$request ->referrer():设定Used to specify the address (URI) of the document from which the requested resouce address was obtained.
$request->user_agent():Client端的软件与版本
$request->content([$content])
设定requset的内容,可以是一个subroutine,LWP会不断invoke这个function直到回传null数值。
$request->content_ref
回传ref to content,可以直接修改内容
$requese->add_content($data)
增加content内容
改变URL内容与method:
$request->uri([$uri])
设定或取出URI内容
$request->method([$method])
设定或取出method内容
$string=$request->as_string
将request内容以文字方式显示出来
一些例子:
发送Email:
$req = HTTP::Request->new(POST => ‘mailto:libwww@perl.org’);
$req->header(Subject => “subscribe”);
$req->content(”Please subscribe me to the libwww-perl mailing list!\n”);
FTP档案:
$req = HTTP::Request->new(GET => ‘file:/etc/passwd’);
与NEWS Server作用:
$req = HTTP::Request->new(GET => ‘news:abc1234@a.sn.no’);
$req = HTTP::Request->new(POST => ‘news:comp.lang.perl.test’);
$req->header(Subject => ‘This is a test’,
From => ‘me@some.where.org’);
$req->content(<<EOT);
This is the content of the message that we are sending to
the world.
EOT
CPAN Request:
$LWP::Protocol::cpan::CPAN = “file:/local/CPAN/”;
HTTP::Response物件:
HTTP::Reponse接收服务器的回应值,没有限定一定要是HTTP协议。
回传的状态码,不管是不是HTTP都回传下列数值:
100-199 状态码从100到199,为要求完成前的状态码
200-299 成功
300-399 重新转向,URL已经被移动至其它地方。
400-499 Client-side 错误
500以上 Server-side 错误
如果Server回传301 或 302,则LWP会对新的URL发出要求,所以回传值,是针对新的URL并非针对旧的URL。
如果Server回传401需要Authorization,而且Authorization信息也存在,则LWP会重新发送存在Authorization的Request到Server端。
HTTP::Response有一个建构子(contructor),但是因为不会去呼叫他,所以以下并没有列出建构子。
$status_code = $response->code
$status_message=$response->message
code()回传状态码,message()回传讯息明码内容,也可以给他参数设定他的数值。
$text=$response->status_line
回传与Web Server传回的内容一样的数值,状态码加上讯息内容。
$boolean=$response->is_success
是否成功
$boolean=$response->is_redirect
是否重新转向
$boolean=$response->is_info
是否是information
$boolean=$response->is_error
是否有错误
$html=$response->error_as_HTML
当is_error为真的时候,利用error_as_HTML产成HTML格式的错误讯系
$base=$response->base
回传base的URL。实际上回传URI对象,可用来解析relative的links。
$request=$response->request
回传HTTP::Request 物件。如果有redirect或authentication则对象内容会与原本的不一样。
$request=$reponse->previous
回传HTTP::Request对象,可以在一连串redirect之后找到原始的HTTP::Request对象内容。
下面是一个找出所有转向过程的Script:
#!/usr/bin/perl
#file follow_chain.pl
use strict;
use LWP;
my $url = shift;
my $agent = LWP::UserAgent->new();
my $request=HTTP::Request->new(HEAD=>$url);
my $response=$agent->request($request);
$response->is_success or die “$url: “, $response->message,”\n”;
my @urls;
for(my $r = $response; defined $r; $r=$r->previous){
unshift @urls,$r->request->uri.’(’.$r->status_line.’)';
}
print “Response chain:\n \t”,join(”\n\t-> “,@urls),”\n”;
LWP ::UserAgent物件:
LWP ::UserAgent的角色在于传送request至远程的Server,接收Server回传值并将之放入HTTP ::Response物件中。其实可以把他当成是一个Web Browser engine。
跟一般的Web browser一样,LWP ::UserAgent可以知道对方的Document是否有更新、储存Cookies、与相对应的authentication并可以透过http Proxy与其它Server相通。
UserAgent通常会被其它Class继承,以适应不同的远程Server内容。
$agent=LWP ::UserAgent->new
建立LWP ::UserAgent物件
$response=$agent->request($request,[$dest[,$size]])
产生Request,并将结果存入$response中。透过$response->code与$response->is_success()可以知道是否有成功。
$dest为一个filename,所取得的文件会存在这个地方,$response只存是否成功没有内容;如果没给,会回传至$response。
也可以是callback subroutine,
$response=$agent->request($request,\&handle_content);
sub handle_content{
my ($data,$response,$protocol) = @_;
…
}
$data :current chunk of data
$response: HTTP::Response 物件
$protocol: LWP::Protocol 物件
当使用ref to code的时候,可以利用$size控制chunk的大小。例如128,则callback subtine每次会读取128 bytes chunks of the content data.
两个request的变形:
$response=$agent->simple_request($request,[$dest,[$size]])
很像request,但是碰到redirect与authentication的时候不会再次产生新的request。
$response=$agent->mirror($url,$file)
接受一个URL与本地储存文件的路径,假如本地文件较旧,则将远程文件抓取回来。
设定Request的时间与空间限制
$timeout = $agent->timeout([$timeout])
设定或读取timeout时间,default 180秒。
$bytes = $agent->max_size([$bytes])
设定或读取远程Server所能回传的最大空间。Default undef,可以不受限制收取content
增加$request的信息
$id=$agent->agent([$id])
设定或取出User-Agent:字段。