2015年9月24日木曜日

HTML::TagParserというPerlモジュールでスパイダリングしてみたよ!

今日は、スパイダリングのスクリプトを作成しました。

起点となるページ(デフォルトでYahoo!ニュース)に飛んで、

同じドメインのページをスパイダリングします。

たぶん幅優先探索になっていると思われます。


とりあえず pタグの innerText を抜きまくって、.txtで保存します。


HTML::TagParserモジュール以外でも作れると思いますし、

もしかすると別のモジュールの方がいいのかもしれません(´・ω・`)ショボーン

実際、Yahoo!ニュースを起点に2000ページほどスパイダリングしたんですが、

かなり時間かかりました。

でも頑張って書いたので、下記をご笑覧ください。




▼Perlスクリプト▼


#!/usr/bin/perl

use strict;
use warnings;
use URI::Fetch;
use HTML::TagParser;
use Encode;

my @contents = ();
print "スパイダリングの起点となるウェブページのURLを入力してください。(半角英数)\n";
print "※デフォルトでYahoo!ニュースが設定されています。\n";

chomp(my $start = <STDIN>);

if($start eq ""){

 $start = "http://news.yahoo.co.jp/";

}

my %links = ($start,1);
my @pages =($start);

print "起点からスパイダリングするページ数を指定してください(半角数字)\n";
chomp(my $intensity = <STDIN>);
print "スパイダリングしています。\n";

foreach my $page ( @pages ){

 my $html = HTML::TagParser->new( $page );
 my @a = $html->getElementsByTagName( "a" );
  
 foreach my $elem ( @a ) {

  my $url = $elem->attributes->{href};
  
  if(defined($url)){
  
   if( $url =~ /$start/ && !defined($links{$url})){

    $links{$url}++;
    $intensity--;

    push(@pages,$url);

   }

  }

 }

 if($intensity<=0){

  last;

 }

}

print "スパイダリング完了。\n";
print "pタグのテキストデータを抽出しています。\n";

foreach my $page ( @pages ){

 my $html = HTML::TagParser->new( $page );
 my @p = $html->getElementsByTagName( "p" );
  
 foreach my $elem ( @p ) {
   
  my $str = decode('UTF-8', $elem->innerText);
   
  my $text = encode('Shift_JIS', $str);
   
  push(@contents,$text);
  
 }

}


unlink './learningData.txt';
open(DATAFILE, ">> ./learningData.txt");

print DATAFILE "@contents\n";

close DATAFILE;

exit;





0 件のコメント:

コメントを投稿