All pastes #810597 Raw Edit

grokker.pl

public text v1 · immutable
·published 2007-12-10 02:32 UTC
rendered paste body
#!/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(<FH>){;
    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 <urlfile.txt>\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");