Perl LWP 编程
最后修改于 2023 年 8 月 24 日
在本文中,我们将展示如何使用 Perl LWP 模块进行 WWW 编程。
LWP 是一组 Perl 模块,它为万维网提供了一个简单一致的应用程序编程接口 (API)。该库的主要重点是提供类和函数来编写 WWW 客户端。LWP 是 Library for WWW in Perl 的缩写。
LWP::Simple
LWP::Simple
是 LWP 的一个简单的过程式接口。它包含一些函数,可以方便地处理网页。LWP::Simple
模块对于简单情况很有用,但它不支持更高级的功能,如 cookie 或授权。
get 函数
get
函数获取由给定 URL 标识的文档并返回它。如果失败,则返回 undef
。$url
参数可以是字符串或 URI 对象的引用。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::Simple; my $cont = get('http://webcode.me') or die 'Unable to get page'; say $cont;
该脚本抓取 http://webcode.me
网页的内容。
$ ./simple_get.pl <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My html page</title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body> </html>
这是 simple_get.pl
脚本的输出。
以下程序获取一个小型网页并去除其 HTML 标签。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::Simple; my $cont = get('http://webcode.me'); foreach ($cont) { s/<[^>]*>//g; print; }
该脚本剥离 http://webcode.me
网页的 HTML 标签。
head 函数
head
函数检索文档头。成功时,它返回以下五个值:内容类型、文档长度、修改时间、过期时间和服务器。如果失败,它返回一个空列表。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::Simple; my ($content_type, $doc_length, $mod_time, $expires, $server) = head("http://webcode.me"); say "Content type: $content_type"; say "Document length: $doc_length"; say "Modification time: $mod_time"; say "Server: $server";
该示例打印 http://webcode.me
网页的内容类型、文档长度、修改时间和服务器。
$ ./simple_head.pl Content type: text/html Document length: 348 Modification time: 1563623365 Server: nginx/1.6.2
getstore 函数
getstore
函数检索由 URL 标识的文档并将其存储在文件中。返回值是 HTTP 响应代码。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::Simple; my $r = getstore('http://webcode.me', 'webcode.html') or die 'Unable to get page'; say "Response code: $r";
该脚本抓取 http://webcode.me
网页的内容并将其存储在 webcode.html
文件中。
$ ./get_store.pl Response code: 200 $ cat webcode.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>My html page</title> </head> <body> <p> Today is a beautiful day. We go swimming and fishing. </p> <p> Hello there. How are you? </p> </body> </html>
可以使用 is_success
函数检查返回代码。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::Simple; my $url = 'http://webcode.mee'; my $r = getstore($url, 'webcode.html') or die 'Unable to get page'; die "Error $r on $url" unless is_success($r);
在示例中,我们故意拼错了网页 URL。
$ ./check_return_code.pl Error 500 on http://webcode.mee at ./check_return_code.pl line 11.
LWP 类模型
LWP 类模型包含用于更复杂地处理万维网的类。
LWP::UserAgent
是一个实现 Web 用户代理的类。在应用程序中,我们创建并配置一个 LWP::UserAgent
对象。然后,我们创建一个 HTTP::Request
实例来执行所需的请求。然后,此请求被传递给用户代理的请求方法之一,该方法使用相关协议进行调度,并返回一个 HTTP::Response
对象。有用于发送最常见请求类型的便利方法:get
、head
、post
、put
和 delete
。
用户代理
LWP::UserAgent
是一个 Web 用户代理类。
$ cpanm Mojolicious::Lite
我们安装 Mojolicious 框架。
#!/usr/bin/perl use Mojolicious::Lite -signatures; get '/' => sub ($c) { my $ua = $c->req->headers->user_agent; $c->render(text => $ua); }; app->start;
服务器处理客户端请求,确定用户代理,并将用户代理返回给客户端。
$ perl server.pl daemon [2021-07-08 13:02:55.63239] [49095] [info] Listening at "http://*:3000" Web application available at http://127.0.0.1:3000
我们启动服务器;它监听端口 3000。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::UserAgent; my $ua = new LWP::UserAgent; $ua->agent('Perl script'); my $req = new HTTP::Request 'GET' => 'https://:3000'; my $res = $ua->request($req); if ($res->is_success) { say $res->content; } else { say $res->status_line; }
此脚本向 localhost 发送一个简单的 GET 请求。
my $ua = new LWP::UserAgent;
创建了 LWP::UserAgent
的实例。
$ua->agent("Perl script");
使用 agent
方法,我们设置代理的名称。
my $req = new HTTP::Request 'GET' => 'https://:3000';
创建了一个到 localhost 的 GET 请求。
my $res = $ua->request($req);
request
方法调度请求对象。返回值是一个响应对象。
if ($res->is_success) { say $res->content; } else { say $res->status_line; }
is_success
方法检查响应是否具有成功的返回代码。content
方法返回原始内容。status_line
返回状态代码和响应消息。
$ ./agent.pl Perl script
服务器响应了我们随请求发送的代理名称。
get 方法
用户代理的 get
方法是一个执行 HTTP 请求的便捷方法。它节省了一些输入。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::UserAgent; my $ua = new LWP::UserAgent; $ua->agent("Perl script"); my $res = $ua->get('http://webcode.me'); if ($res->is_success) { say $res->content; } else { say $res->status_line; }
该脚本获取 webcode.me
页面的内容。我们使用了便捷的 get
方法。
在下面的示例中,我们在 urbandictionary.com 上查找一个术语的定义。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::UserAgent; use HTML::TreeBuilder; my $word = shift || 'dog'; my %parameters = (term => $word); my $url = URI->new('https://www.urbandictionary.com/define.php'); $url->query_form(%parameters); my $ua = LWP::UserAgent->new; my $res = $ua->get($url); my $tree = HTML::TreeBuilder->new_from_content($res->decoded_content); my @meanings = $tree->look_down(_tag => q{div}, 'class' => 'meaning'); foreach my $el (@meanings) { say $el->as_text; } die "Error: ", $res->status_line unless $res->is_success;
在此脚本中,我们在 urbandictionary.com
上查找术语 dog 的定义。我们显示来自第一页的定义。HTML::TreeBuilder
用于解析 HTML 代码。
发布一个值
post
方法在给定的 URL 上分派一个 POST 请求,为表单填写内容提供键/值对。
#!/usr/bin/perl use Mojolicious::Lite -signatures; post '/' => sub ($c) { my $name = $c->param('name'); $c->render(text => "Hello $name!"); }; app->start;
在处理程序中,我们获取 name 参数。根据该参数,我们构建一个消息并将其发送给客户端。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $res = $ua->post('https://:3000/', ['name' => 'Jan']); if ($res->is_success) { say $res->content; } else { say $res->status_line; }
该脚本发送一个带有 Jan
值的 name
键的请求。
$ ./post_value.pl Hello Jan!
凭据
用户代理的 credentials
方法设置要用于某个域的名称和密码。安全域是用于保护 Web 应用程序资源的一种机制。
$ sudo apt-get install apache2-utils $ sudo htpasswd -c /etc/nginx/.htpasswd user7 New password: Re-type new password: Adding password for user user7
我们使用 htpasswd
工具为基本 HTTP 身份验证创建一个用户名和密码。
location /secure { auth_basic "Restricted Area"; auth_basic_user_file /etc/nginx/.htpasswd; }
在 nginx 的 /etc/nginx/sites-available/default
配置文件中,我们创建一个受保护的页面。该领域的名称是“Restricted Area”。
<!DOCTYPE html> <html lang="en"> <head> <title>Secure page</title> </head> <body> <p> This is a secure page. </p> </body> </html>
在 /usr/share/nginx/html/secure
目录中,我们有这个 HTML 文件。
#!/usr/bin/perl use 5.30.0; use warnings; use LWP::UserAgent; my $ua = new LWP::UserAgent; $ua->agent("Perl script"); $ua->credentials('localhost:80', 'Restricted Area', 'user7' => 's$cret'); my $res = $ua->get('https:///secure/'); if ($res->is_success) { say $res->content; } else { say $res->status_line; }
该脚本连接到受保护的网页;它提供访问该页面所需的用户名和密码。
$ ./credentials.pl <!DOCTYPE html> <html lang="en"> <head> <title>Secure page</title> </head> <body> <p> This is a secure page. </p> </body> </html>
使用正确的凭据,credentials.pl
脚本会返回安全页面。
在本文中,我们使用了 Perl LWP 模块。
作者
列出 所有 Perl 教程。