LWP与WEB的基本使用Word文件下载.docx
《LWP与WEB的基本使用Word文件下载.docx》由会员分享,可在线阅读,更多相关《LWP与WEB的基本使用Word文件下载.docx(15页珍藏版)》请在冰点文库上搜索。
![LWP与WEB的基本使用Word文件下载.docx](https://file1.bingdoc.com/fileroot1/2023-5/11/455b1228-e48d-4b68-b7b9-bc9576512217/455b1228-e48d-4b68-b7b9-bc95765122171.gif)
}else{
FreshAirisapparentlyjazzlesstoday.\n"
}
如果要在命令行里运行,getprint函数非常方便。
如果没有发生错误,它会把网页内容输出到STDOUT,否则将会有错误信息输出到STDERR。
例如:
%perl-MLWP:
Simple-e"
getprint'
//cpan.org/RECENT'
"
上面的网址指向一个文本文件,列有最近两个星期内CPAN更新过的文件。
如果想要知道Acme:
的模块是否有更新,有就email自己,你可以把它和Shell结合到一起来实现。
如下:
|grep"
/by-module/Acme"
|mail-s"
NewAcmemodules!
Joy!
$USER
LWP:
Simple还有一些非常有用的函数,包括一个运行HEAD请求的函数,用来检查链接是否有效,网页是否更新。
另外两个用来保存和镜像网址的函数也值得一提。
具体请看LWP:
Simple的文档或Perl&
LWP的第二章.
LWPClass模型基础
Simple在做简单的工作时很方便。
但因为不支持cookies,用户认证,对HTTPrequestheader(请求标头)的编辑,和HTTPresonseheader(响应标头)的读写(主要是HTTP的errormessage)。
因此,当需要这些特性的时候,就要使用LWPClass模型。
在众多的LWPClass里,LWP:
UserAgent和HTTP:
Response是必须理解的。
UserAgent就像一个虚拟浏览器用来作request(请求)。
HTTP:
Response用来储存request(请求)生成的response(响应)。
最基本的用法是$response=$browser->
get($url),或写的更完整些:
#程序开始:
useLWP5.64;
#载入较新版本的LWPclasses
my$browser=LWP:
UserAgent->
new;
...
#getrequest:
my$response=$browser->
get($url);
Can'
tget$url--"
$response->
status_line
unless$response->
is_success;
die"
Hey,我想要HTML格式而不是"
content_type
content_typeeq'
text/html'
#或者任何其他的content-type
#成功的话就对内容处理
if($response->
content=~m/jazz/i){
print"
FreshAir今天在讨论爵士乐!
FreshAir今天讨论的和爵士乐一点边都不沾.\n"
上面有两个相关的object:
$browser,是LWP:
UserAgent的一个object。
$response是属于HTTP:
Response类的一个object。
一个程序里只需要一个$browserobject,但是每次发出一个request,就会得到一个新的HTTP:
Responseobject。
Responseobject有以下一些有价值的属性:
∙一个statuscode(状态代码值),表示成功或失败。
你可以使用$response->
is_success来检测它。
∙httpstatusline(http状态描述),观察$response->
status_line的结果(比如“404NotFound”)会帮助你理解这个词的意思。
∙MIMEcontent-type(文件类型)通过$response->
content_type来获得。
例如“text/html”,”image/gif”,”application/xml”等等。
∙contentoftheresponse(响应返回的内容)储存在$response->
content。
内容可能是html格式。
如果是GIF格式,$response->
content里是二进制的GIF数据。
∙许多其他methods都可以在HTTP:
Response和它的superclasses(父class)HTTP:
Message和HTTP:
Headers里找到。
添加其他HTTP请求headers
request(请求)常用的方法是$response=$browser->
get($url),但如果需要,你可以在$url后跟一个键值的列表来给你的request加上其他HTTPheaders。
象这样:
$response=$browser->
get($url,$key1,$value1,$key2,$value2,...);
举个例子,如果你要对一个只允许Netscape浏览器连入的网站发出请求,那就需要发出类似Netscape的header,如下:
my@ns_headers=(
'
User-Agent'
=>
Mozilla/4.76[en](Win98;
U)'
Accept'
image/gif,image/x-xbitmap,image/jpeg,
image/pjpeg,image/png,*/*'
Accept-Charset'
iso-8859-1,*,utf-8'
Accept-Language'
en-US'
);
get($url,@ns_headers);
如果不打算重复使用这个array,你可以把它写到get函数里
get($url,
如果只是打算修改User-Agent,可以通过LWP:
UserAgent的agent方法把缺省的agent‘libwww-perl/5.65’(或者别的)改掉。
$browser->
agent('
);
使用cookies
默认的LWP:
UserAgent对象像一个不支持cookies的浏览器一样工作。
有不只一种的办法可以设定它的cookie_jar属性,从而让它支持cookies。
“cookiejar”是一个用来储存HTTPcookie的容器。
你可以把它存到硬盘(像Netscape使用cookies.txt一样)或内存里。
存到内存里的cookies会在程序完成后消失。
内存式的cookie使用方法:
cookie_jar({});
也可以把cookie储存到硬盘的文件里:
useHTTP:
Cookies;
cookie_jar(HTTP:
Cookies->
new(
file'
/some/where/cookies.lwp'
#储存cookies的地址
autosave'
1,
#当完成后自动储存到硬盘里
));
文件里的cookie是以LWP自定的格式储存,如果你想在netscape里使用这个cookie文件,可以使用HTTP:
Cookies:
Netscapeclass:
#yes,loadsHTTP:
Netscapetoo
Netscape->
c:
/ProgramFiles/Netscape/Users/DIR-NAME-HERE/cookies.txt'
#wheretoreadcookies
你也可以象上面一样使用‘autosave’=>
1。
但Netscape的cookie有时会在写入硬盘之前就被丢掉,至少在写这篇文章的时候还是这样。
通过POST提交表格
大部分HTML表格使用HTMLPOST向服务器提交数据,在这里你可以这样:
post($url,
[
formkey1=>
value1,
formkey2=>
value2,
],
或者你也可以把HTTPheader也一起发出
headerkey1=>
headerkey2=>
下一个例子向AltaVista的搜索引擎发送HTTPPOST请求,然后从HTML里提取出符合匹配的总数。
usestrict;
usewarnings;
useLWP5.64;
my$word='
tarragon'
['
q'
$word,#theAltavistaquerystring
pg'
'
avkw'
tgz'
kl'
XX'
]
$urlerror:
"
Weirdcontenttypeat$url--"
if($response->
content=~m{AltaVistafound([0-9,]+)results}){
#从"
AltaVistafound2,345results"
里匹配出结果
$word:
\n"
tfindthematch-stringintheresponse\n"
通过GET提交表格
一些HTML表格不使用POST请求,而是使用GET请求来传输数据。
例如,在里检索电影名字‘BladeRunner’,提交后在浏览器的网址栏里将显示:
下面是使用LWP实现同样的结果:
useURI;
my$url=URI->
new('
#makesanobjectrepresentingtheURL
$url->
query_form(#Andheretheformdatapairs:
title'
BladeRunner'
restrict'
MoviesandTV'
get($url);
第5章详细描述了HTML表格和表格数据,第6章到第9章描述了怎样从获得的HTML数据里提取出有用的信息。
URL处理
上面提到的URIclass提供很多获取和修改URL的方法。
例如如果想要知道url是什么类型(http,ftp等等)可以使用$url->
schema来得到,如果要提取网址里的主机名,可以使用$url->
host。
不过,可能最有用的是我前面提到的query_form方法,以及把相对网址路径(如”../foo.html”)转换成绝对路径(如”
$abs=URI->
new_abs($maybe_relative,$base);
现在回忆一下获取最新CPAN模块的那个例子。
//www.cpan.org/RECENT.html'
my$html=$response->
content;
while($html=~m/chunk86920392chunklt;
AHREF=\"
(.*?
)\"
/g){
输出的结果是
MIRRORING.FROM
RECENT
RECENT.html
authors/00whois.html
authors/01mailrc.txt.gz
authors/id/A/AA/AASSAD/CHECKSUMS
...
你可以使用URI模块的new_abs方法来得到完全网址路径,修改while循环:
while($html=~m/<
printURI->
new_abs(,$response->
base),"
$response->
base方法可以在HTTP:
Message里找到。
它返回的URL通常被用来和相对路径合并来得到完全路径。
现在得到的结果是
http:
//www.cpan.org/MIRRORING.FROM
//www.cpan.org/RECENT
//www.cpan.org/RECENT.html
//www.cpan.org/authors/00whois.html
//www.cpan.org/authors/01mailrc.txt.gz
//www.cpan.org/authors/id/A/AA/AASSAD/CHECKSUMS
请参考Perl&
LWP的第四章,以得到对URIobjects更详细的描述。
当然,使用regexp(正则表达式)来匹配url相对简单,如果情况复杂,需要更强大的匹配工具,可以考虑HTML分析模块HTML:
LinkExtor或HTML:
TokeParser,甚至HTML:
TreeBuilder
其他浏览器属性
UserAgentobjects有几个值得注意的属性:
∙$browser->
timeout(15):
设定缺省request的timeout时间.超过这个时间就放弃请求。
protocols_allowed([‘http’,‘gopher’]):
这用来设定只接受http和gopher协议。
连接其他协议时就返回500错误值,”AccesstoftpURIshasbeendisabled”的错误消息。
∙useLWP:
ConnCache;
conn_cache(LWP:
ConnCache->
new()):
这告诉browserobject使用HTTP/1.1“keep-Alive”特性,即重复使用先前的socket来加快请求速度。
agent(‘SomeName/1.23(moreinfoheremaybe)’):
设置HTTP请求的User-Agent。
LWP缺省使用“libwww-perl/versionnumber”作为User-Agent,比如“libwww-perl/5.65”。
你可以加上更多的信息:
∙$browser->
agent(‘SomeName/3.14(contact@robotplexus.int)’);
或者可以伪装为
agent(‘Mozilla/4.0(compatible;
MSIE5.12;
Mac_PowerPC)’);
∙push@{$ua->
requests_redirectable},‘POST’:
告诉LWP在POST请求发送后如果发生重新定向就自动跟随(虽然RFC里不要求这么做)
详细请参见LWP:
UserAgent文档.
写一个有礼貌的机器人
如果想遵循robots.txt和避免在较短的时间发出太多的请求,你可以采用LWP:
RobotUA而不是LWP:
UserAgent。
RobotUA用法与LWP:
UserAgent一样:
RobotUA;
RobotUA->
YourSuperBot/1.34'
you@'
#机器人名字和email地址
RobotUA多了几个特性:
∙如果$url请求的服务器的robots.txt禁止了你对$url的访问,那么$browser就不会发出对于这个地址的请求,而是返回403代码和一个错误信息“Forbiddenbyrobots.txt”。
∙die"
$url--"
status_line,"
\nAborted"
∙unless$response->
然后你会得到这样的错误信息:
//whatever.site.int/pith/x.html--403Forbidden
byrobots.txt
Abortedatwhateverprogram.plline1234
∙如果$browser发现请求的地址是刚刚请求过的,就会暂停(sleep)来避免发送太多的请求。
缺省暂停1分钟,但可以通过$browser->
delay(minutes)来设定。
比如:
delay(7/60);
RobotUA文档.
使用代理
有时你希望(或者是必须)通过代理来连接某些站点或协议,就比如你的LWP程序是运行在某台处于防火墙之内的机器上。
代理通常储存在环境变量HTTP_PROXY里。
LWP可以通过user-agentobject里的env_proxy函数把环境变量里的代理地址装载。
UserAgent;
#Andbeforeyougomakinganyrequests:
env_proxy;
详细请参照LWP:
UserAgent文档里的proxy,env_proxy和no_proxy方法.
HTTP认证
许多网站都是通过HTTP认证来限制连接.当用户请求一个限制页面时,HTTP服务器回复“Thatdocumentispartofaprotected‘realm’andyoucanaccessitonlyifyoure-requestitandaddsomespecialauthorizationheaderstoyourrequest”.(你现在请求了一个限制区域,如果你需要重新发送一个带有认证信息的header才可以连入.)
Unicode.org的管理员为了防止机器人访问邮件组获取发信人地址,