这是我的做法Mojo::DOM https://docs.mojolicious.org/Mojo/DOM。获取 HTML 页面后,使用dom
完成所有解析。由此,使用 CSS 选择器来查找感兴趣的节点:
link[rel*=icon i][href]
这个CSS选择器寻找link
具有以下内容的标签rel
and href
同时标记。此外,我要求该值rel
包含 (*=
) “图标”,不区分大小写(i
)。如果你想假设所有节点都有href
,就离开吧[href]
.
一旦我有了链接列表,我就只提取其中的值href
并将该列表转换为数组引用(尽管我可以用Mojo::Collection
方法):
use v5.10;
use Mojo::UserAgent;
my $ua = Mojo::UserAgent->new->max_redirects(3);
my $results = $ua->get( shift )
->result
->dom
->find( 'link[rel*=icon i][href]' )
->map( attr => 'href' )
->to_array
;
say join "\n", @$results;
到目前为止效果很好:
$ perl mojo.pl https://www.perl.org
https://cdn.perl.org/perlweb/favicon.ico
$ perl mojo.pl https://www.microsoft.com
https://c.s-microsoft.com/favicon.ico?v2
$ perl mojo.pl https://leanpub.com/mojo_web_clients
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-57x57-b83f183ad6b00aa74d8e692126c7017e.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-60x60-6dc1c10b7145a2f1156af5b798565268.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-72x72-5037b667b6f7a8d5ba8c4ffb4a62ec2d.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-76x76-57860ca8a817754d2861e8d0ef943b23.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-114x114-27f9c42684f2a77945643b35b28df6e3.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-120x120-3819f03d1bad1584719af0212396a6fc.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-144x144-a79479b4595dc7ca2f3e6f5b962d16fd.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/apple-touch-icon-152x152-aafe015ef1c22234133158a89b29daf5.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/favicon-16x16-c1207cd2f3a20fd50de0e585b4b307a3.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/favicon-32x32-e9b1d6ef3d96ed8918c54316cdea011f.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/favicon-96x96-842fcd3e7786576fc20d38bbf94837fc.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/favicon-128x128-e97066b91cc21b104c63bc7530ff819f.png
https://d3g6anj9jkury9.cloudfront.net/assets/favicons/favicon-196x196-b8cab44cf725c4fa0aafdbd237cdc4ed.png
现在,如果您发现更有趣的情况而您无法轻松为其编写选择器,那么问题就来了。假设不是所有的rel
价值观中有“图标”。您可以通过指定用逗号分隔的多个选择器来获得更奇特的效果,这样您就不必使用实验性的不区分大小写标志:
link[rel*=icon][href], link[rel*=ICON][href]
或不同的值rel
:
link[rel="shortcut icon"][href], link[rel="apple-touch-icon-precomposed"][href]
根据需要排列任意多个。
但是,您也可以在没有选择器的情况下过滤结果。使用 Mojo::Collection 的grep
选择您想要的节点:
my %Interesting = ...;
my $results = $ua->get( shift )
->result
->dom
->find( '...' )
->grep( sub { exists $Interesting{ $_->attr('rel') } } )
->map( attr => 'href' )
->to_array
;
我还有很多例子Mojo::DOM
in Mojo 网络客户端 https://leanpub.com/mojo_web_clients,我想我现在就添加这个例子。