A short Mojo::DOM example to provide an alternative viewpoint:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Mojo::DOM;
my $html = '<!doctype html>
<html class="no-focus-outline no-js"
lang="en-US" data-modal-active="true">
<head>
<title>test</title>
</head>
<body>
<h1>test heading</h1
<div>
<p>paragraph one
<a href="https://example.com/one/two.html">one</a> example.</p>
<p>paragraph two
<a href="https://example.com/two/three.html">another</a> example.</p>
</div>
</body>
</html>';
my $dom = Mojo::DOM->new( $html );
foreach my $e ( $dom->find('p > a')->each ){
say $e->{'href'};
}
# or
$dom->find('p > a')->each(sub { say $_->{'href'} } );
If the HTML is live you can access all of the above via Mojo::UserAgent, see this example.