Mojo::DOM
(或任何其他框架)解析网页时,提取相对或绝对的资源地址是相当常见的。有没有快捷方法可以将这样的资源地址转换为绝对URL?
mojo
命令会拉取 mojolicio.us 上的所有样式表:
$ mojo get http://mojolicio.us "link[rel=stylesheet]" attr href
/mojo/prettify/prettify-mojo-light.css
/css/index.css
URI
将资源转换为绝对 URL。
use strict;
use warnings;
use Mojo::UserAgent;
use URI;
my $url = 'http://mojolicio.us';
my $ua = Mojo::UserAgent->new;
my $dom = $ua->get($url)->res->dom;
for my $csshref ($dom->find('link[rel=stylesheet]')->attr('href')->each) {
my $cssurl = URI->new($csshref)->abs($url);
print "$cssurl\n";
}
输出:
http://mojolicio.us/mojo/prettify/prettify-mojo-light.css
http://mojolicio.us/css/index.css
显然,此上下文中的相对 URL 应该使用加载 DOM 的 URL 设为绝对 URL。但是,除了自己编码之外,我不知道如何获取资源绝对 URL。
中有
Mojolicious
。但是,我不知道这是否会以某种方式与 Mojo::DOM
集成,并且它本身会比 URI
需要更多的代码。
我理想的解决方案是,如果脚本和命令行都可以实现类似以下内容,但寻找使用 Mojo 进行解析的任何相关见解:
mojo get http://mojolicio.us "link[rel=stylesheet]" attr href to_abs
我不确定为什么您认为使用
Mojo::URL
需要更多代码?在下面的示例中,我从交易中获取实际的请求 URL(可能存在我允许的重定向),我将其称为 $base
。
然后,由于
$base
是 Mojo::URL
的实例,我可以使用 $base->new
创建一个新实例。当然,如果这看起来太神奇,你可以用Mojo::URL->new
替换它。
use Mojo::Base -strict;
use Mojo::UserAgent;
my $url = 'http://mojolicio.us';
my $ua = Mojo::UserAgent->new->max_redirects(10);
my $tx = $ua->get($url);
my $base = $tx->req->url;
$tx->res
->dom
->find('link[rel=stylesheet]')
->map(sub{$base->new($_->{href})->to_abs($base)})
->each(sub{say});