使用模块在循环外创建对象获取绝对URL

时间:2017-07-02 09:27:35

标签: perl

我怀疑我一直在尝试使用CPAN模块文档解决自己,但我有点新,我对不同模块中的一些术语和部分感到困惑。

我正在尝试在下面的代码中创建对象,并获取从网站提取的相对链接的绝对URL。

#!/usr/bin/perl

use strict;
use warnings;
use LWP::UserAgent;         
use Digest::MD5 qw(md5_hex);
use URI;

my $url = $ARGV[0];

if ($url !~ m{^https?://[^\W]+-?\.com/?}i) {
    exit(0);                         
}      

my $ua = LWP::UserAgent->new;
$ua->timeout( 10 );

my $response = $ua->get( $url );  

my $content = $response->decoded_content();

my $links = URI->new($content);
my $abs = $links->abs('http:', $content);
my $abs_links = $links->abs($abs);

while ($content =~ m{<a[^>]\s*href\s*=\s*"?([^"\s>]+)}gis) {
    $abs_links = $1;
    print "$abs_links\n";
    print "Digest for the above URL is " . md5_hex($abs_links) . "\n";             
}

问题是当我尝试在While循环(循环前面的3行块)之外添加该部分时,它不起作用,而如果我在While循环中添加相同的部分,它将正常工作。这个只是获取给定网站的相对URL,但不打印“Http:// ...”,而是打印“//...".

适用于我的脚本如下:

#!/usr/bin/perl
use strict;
use warnings;

use LWP::UserAgent;            
use Digest::MD5 qw(md5_hex);
use URI::URL;

my $url = $ARGV[0];                            ## Url passed in command
if ($url !~ m{^https?://[\w]+-?[\w]+\.com/?}i) {
    exit(0);                                   ## Program stops if not valid URL
}         

my $ua = LWP::UserAgent->new;
$ua->timeout( 10 );

my $response = $ua->get( $url );               ## Get response, not content

my $content = $response->decoded_content();    ## Now let's get the content

while ($content =~ m{<a[^>]\s*href\s*=\s*"?([^"\s>]+)}gis) {    ## All links
    my $links = $1;
    my $abs = new URI::URL "$links";
    my $abs_url = $abs->abs('http:', $links);
    print "$abs_url\n";
    print "Digest for the above URL is " . md5_hex($abs_url) . "\n";              
} 

有什么想法吗?非常感谢。

2 个答案:

答案 0 :(得分:1)

我不理解你的代码。有一些奇怪的事情:

  • [^\W]\w
  • 相同
  • 正则表达式允许选择-之前和/之后的.comhttp://bitwise.complement.biz匹配但http://cool-beans.com不匹配。
  • URI->new($content)毫无意义:$content是随机HTML,而不是URI。
  • $links->abs('http:', $content)毫无意义:$content被忽略,$links->abs('http:')尝试使$links成为相对于'http:'的绝对网址,但{{1} }}不是有效的网址。

以下是我认为您正在尝试做的事情:

'http:'
  • 我没有尝试验证#!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use HTML::LinkExtor; use Digest::MD5 qw(md5_hex); @ARGV == 1 or die "Usage: $0 URL\n"; my $url = $ARGV[0]; my $ua = LWP::UserAgent->new(timeout => 10); my $response = $ua->get($url); $response->is_success or die "$0: " . $response->request->uri . ": " . $response->status_line . "\n"; my $content = $response->decoded_content; my $base = $response->base; my @links; my $p = HTML::LinkExtor->new( sub { my ($tag, %attrs) = @_; if ($tag eq 'a' && $attrs{href}) { push @links, "$attrs{href}"; # stringify } }, $base, ); $p->parse($content); $p->eof; for my $link (@links) { print "$link\n"; print "Digest for the above URL is " . md5_hex($link) . "\n"; } 中传递的网址。留给LWP :: UserAgent。 (如果您不喜欢这样,只需将支票添加回来。)
  • 我确保$ARGV[0]成功后再继续。
  • 我从$response->base获取绝对相对链接的基本网址。
  • 我使用HTML::LinkExtor来解析内容,提取链接,并使它们成为绝对的。

答案 1 :(得分:1)

我认为你最大的错误是尝试使用正则表达式解析HTML中的链接。建议您使用CPAN模块。我建议WWW::Mechanize,这将使您的代码看起来像这样:

if

对我来说这看起来简单得多。