#!/usr/bin/perl -Tw # email web grokker v1.0 use strict; my $MAX_DEPTH = 3; my $debug = undef; my $urlfile = undef; my $emailsfile = "emails.log"; my $nested = 0; my @urls; my %addy; my %emails; my %html; my %links; BEGIN { eval qq{ use LWP::UserAgent; use HTTP::Request::Common qw(POST GET); use HTML::Tree; use HTML::Element; use Email::Valid; use URI; }; } &initialize(); #### initialize variables and blah blah blah... get_urls($urlfile); #### load up list of the main urls from file for (my $i=0; $i<=$#urls; $i++){ my $url = $urls[$i]; log_grokker("Processing url: $url") if defined $debug; $html{$url} = retr_html($url); #### takes scalar of url as arg, returns ref to scalar of html #print ${$html{$url}} && exit if defined $debug; $emails{$url} = grok_emails($url); #### takes scalar of url as arg, returns ref of array of email addresses #print ref $emails{$url} && exit if defined $debug; $links{$url} = grok_links($url); #### takes scalar of url as arg, returns ref of array of urls, derefs $html{$url} #print ref $links{$url} && exit if defined $debug; } for my $key (keys %links){ savelinks($key,@{$links{$key}}); #### fld++ } &dump_emails(); sub dump_emails{ my $emls = ""; for (keys %addy){ $emls .= $_."\n"; } open (FH, ">>$emailsfile"); print FH $emls; close (FH); } sub savelinks { #### fld++ my $parent = shift; $nested++; for my $link (@_) { next if exists $links{$link}; log_grokker("Processing url: $link") if defined $debug; $html{$link} = retr_html($link); next if !defined $html{$link}; $links{$link} = grok_links($link); $emails{$link} = grok_emails($link); if($nested <= $MAX_DEPTH) { savelinks($link, @{$links{$link}}); } } } sub grok_emails { my $url = $_[0]; my $return; while (${$html{$url}} =~ /([a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z])/gi){ my $addy = $1; if (Email::Valid->address($addy)){ push (@{$return},$addy); $addy{$addy}++; } } return $return; } sub grok_links { ##### takes scalar of url as arg, and returns ref to array of links ##### derefs $html{$url} my $url = $_[0]; my $return = undef; my $tree = HTML::TreeBuilder->new; $tree->parse("${$html{$url}}"); $tree->elementify(); #log_grokker ("Extracting links in \"$url\"") if defined $debug; for (@{$tree->extract_links}){ my $abs_link = absolutize (scalar ${$_}[0], $url); next if $abs_link =~ /^mailto\:.*/i; next if scalar ${$_}[0] =~ /(\.js|\.gif|\.jpg|\.jpeg|\.css)$/i; next if exists $links{$url}; #log_grokker("Found link in parent $url:\"$abs_link\"") if defined $debug; push (@{$return}, $abs_link); } $tree->delete(); return $return; } sub retr_html { #### takes scalar of url as arg, returns ref to scalar of html my $url = $_[0]; my $return = undef; #log_grokker ("Retrieving html for \"$url\"") if defined $debug; my $Converter = "$url"; my $ua = new LWP::UserAgent; $ua->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)'); #$ua->agent("Mozilla/4.5 " . $ua->agent); $ua->timeout(10); my $req = GET $Converter; my $res = $ua->request($req); if ($res->is_success) { my $html = $res->as_string; if ($html !~ /href/i){ log_grokker ("WARNING: no links found in doc: \"$url\""); } else { } $return = \$html; } return $return; } sub absolutize { my($url, $base) = @_; return URI->new_abs($url, $base)->canonical; } sub get_urls { open (FH,$urlfile); while(){; chomp; $_ = 'http://'.$_ if $_ !~ /^http/i; push (@urls, $_); } close(FH); my $total = $#urls+1; log_grokker ("loaded up $total urls from \"$urlfile\""); } sub usage { print "Usage:\n\t$0 \n\n"; exit; } sub initialize { usage() if !defined $ARGV[0]; $urlfile = $ARGV[0]; if (defined $ARGV[1] && $ARGV[1] =~ /debug/i){ $debug = 1; } } sub get_date { my @days = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); #my @months = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); my @months = ('01','02','03','04','05','06','07','08','09','10','11','12'); my ($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[0,1,2,3,4,5,6]; my $time = sprintf("%02d\:%02d\:%02d",$hour,$min,$sec); $year += 1900; #return "$days[$wday] $months[$mon] $mday, $year $time"; return "$year-$months[$mon]-$mday-$time"; } sub log_grokker { my $today = get_date(); open (GH, ">>log"); print "$today $0: $_[0]\n" if defined $debug; print GH "$today $0: $_[0]\n"; close (GH); } exit unless defined $debug; my $urlcount=0; my $emlscount=0; for my $key (keys %links){ #for (@{$links{$key}}){ print "key=\"$key\" value=\"$_\"\n"; } #print "key=\"$key\" value=\"$links{$key}\"\n"; #print "$key\n"; $urlcount++; } print ("Total urls found: $urlcount\n"); for (keys %addy){ #print "$_\n"; $emlscount++; } print ("Total emails found: $emlscount\n");