13 February 2011

(Perl HTML::LinkExtor) HTMLファイルからA LINKのURLを抜き出す

HTMLファイルの <a href="...."> 部分のURLを簡単に抜き出すスクリプト

スクリプトの引数に「ファイル名を指定」してもよいし、パイプ(”<”)で流しこんでもよいし… どちらの方法でも処理可能

#!/usr/bin/perl
use strict;
use warnings;
use HTML::LinkExtor;
 
my $file = shift || '';
 
if($file ne '' && !(-f $file)){
    print("error: file '".basename($file)."' not found\n");
    exit();
}
 
my $p = HTML::LinkExtor->new(\&callback);
sub callback {
    my($tag, %links) = @_;
    # <A HREF=...> の場合のみ読み込む
    if(lc($tag) eq 'a' && defined($links{'href'}) && length($links{'href'})>0){
        print($links{'href'}."\n");
    }
}
 
if($file eq ''){ $p->parse(join('', <>)); }     # 標準入力から読み込む
else{ $p->parse_file($file); }      # ファイルから読み込む

コールバック関数を、インラインにしたほうが分かりやすいかも知れない。修正部分は次のようになる。

my $p = HTML::LinkExtor->new(
        sub { # callback sub (inline)
            my($tag, %links) = @_;
            # <A HREF=...> の場合のみ読み込む
            if(lc($tag) eq 'a' && defined($links{'href'}) && length($links{'href'})>0){
            print($links{'href'}."\n");
        }
    });

さらに、コールバック関数内で表示するのではなく、一旦配列に格納してから表示するようにすることも出来る。(配列の内容を、好きなようにいじれる)

my @arr_extracted;
 
my $p = HTML::LinkExtor->new(\&callback);
my $p = HTML::LinkExtor->new(
        sub { # callback sub (inline)
            my($tag, %links) = @_;
            # <A HREF=...> の場合のみ読み込む
            if(lc($tag) eq 'a' && defined($links{'href'}) && length($links{'href'})>0){
            print($links{'href'}."\n");
        }
    });
 
if($file eq ''){ $p->parse(join('', <>)); }     # 標準入力から読み込む
else{ $p->parse_file($file); }      # ファイルから読み込む
 
foreach my $str (@arr_extracted){
    print $str."\n";
}

■ 参考資料
とあるページからリンクするページをいっぺんにダウンロードする
perl でリンクを抽出する