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 教程。