Avatar billede edelbo Nybegynder
18. juni 2002 - 22:18 Der er 1 løsning

Lidt hjælp til ændring af et script...

Hej Perl eksperter,

Jeg har et perl script som gør følgende:
1)Crawler andre sider vha. wget. Sider der skal hentes fra er sat i filen sites.txt
2)Når links med brugernavn og passwords er hentet, altså links. ex.
http://bruger:pass@site.com/blablabla/
så bliver disse links checket via wget.
3)Alle links der stadig virker, bliver smidt ind i en ny fil, som så til sidst bliver samlet til en html side.

Jeg kunne godt tænke mig at få lavet et par ændringer.
1)Den skal ikke crawle andre sider, kun crawle nogle links som jeg selv smider ind i filen wgetchk.txt.
Den skal så tjekke disse links et efter et (koden er der allerede).
Når den har tjekket alle links med bruger:pass fra ovenstående fil, så bliver alle de links som stadig virker kopieret over i filen links.txt, men bliver også stadig i filen wgetchk.txt, så de kommer med næste gang at der tjekkes links. Det eneste som der skal slettes fra wgetchk.txt er alle links hvor bruger:pass ikke virker mere.

Håber at nogle kan hjælpe med dette, hvis I ikke forstår så meget af det, så må i meget gerne spørge, ellers tag et kig på koden nedenunder, den giver nok mere mening. Hvis i får brug for flere filer, så sig endelig til.

Når i begynder at kigge på det, vil i så ikke godt lige skrive det her, da det måske kan tage lidt tid, så jeg ved at nogle kigger på det, og ikke behøves at lukke spørgsmålet.

For evt. adhos questions kan jeg kontaktes her eller på icq: 71849092

Her kommer al koden:

#!/usr/bin/perl
############
#

require "general.pl";

LogTxt( "Start of crawler." );

$datafile="sites.txt";
$linksfile="links.txt";
$chkfile="wgetchk.txt";
$sponsor="sponsors.txt";
$descriptions="descriptions.txt";
$blacklist="blacklist.txt";
$redirfile="redir.txt";
$logfile="extreme.txt";
$tables = "tables.htm";

$numberOfLinksPerTable = 15;

$time_out=3;

$path="../";

# Figure out operating system (is it Windows or something else)

$os = $^O;
if ($os eq 'MSWin32') {
  $isWin = 1;
}
else {
  $isWin = 0;
}

#print "os $os iswin $isWin\n";

@head=("head.htm","head.htm","head.htm","head.htm","head.htm","head.htm","head.htm");
@foot=("foot.htm","foot.htm","foot.htm","foot.htm","foot.htm","foot.htm","foot.htm");

if (!$isWin) {
  # Hello Brian, this is your testing!
  @page=("index.php","page2.htm","page3.htm","page4.htm","page5.htm","page6.htm","page7.htm");
}
else {
  # This is how it runs at my place
  @page=("index.html","page2.htm","page3.htm","page4.htm","page5.htm","page6.htm","page7.htm");
}

$supchk  = 0; # Set to 1 if link check shall be suppressed
$supwget  = 0; # set to 1 if wget shall be suppressed during link check
$linktest = 0; # Set to 1 for testoutput during link search in html from sites
$savtest  = 0; # set to 1 for testoutput of the password save/restore handling
$wgtest  = 0; # set to 1 for testoutput of the link checking process
$suplink  = 0; # set to 1 to suppress generation of new version of links.txt

$max=200;
###################################################

####################################3
# PAss Spider


# Handle program arguments

foreach my $arg (@ARGV) {
  if ($arg eq 'supchk')  { $supchk  = 1; }
  if ($arg eq 'supwget')  { $supwget  = 1; }
  if ($arg eq 'linktest') { $linktest = 1; }
  if ($arg eq 'savtest')  { $savtest  = 1; }
  if ($arg eq 'wgtest')  { $wgtest  = 1; }
  if ($arg eq 'suplink')  { $suplink  = 1; }
}

readRating( '' );

open(DATAFILE,"$datafile") || LogTxt( "cannot open $datafile" );
@sites=<DATAFILE>;
close(DATAFILE);

$c=0;
foreach $line (@sites) {
  $site[$c]=$line,$c++ unless($line =~ /#/);

}
###############################
################################
open(DATAFILE,"$descriptions") || LogTxt( "cannot open $descriptions" );
@sitess=<DATAFILE>;
close(DATAFILE);

$"="|";
$c=0;
foreach $line (@sitess){
    if($line !~ /#/) {
        ($sitename,$cateogry,$rating,$description,@more)=split(/\|/,$line);
        $DESCRIPTION{$sitename}=$description;
        $RATING{$sitename}=$rating;
        $CATEGORY{$sitename}=$rating;
        $MORE{$sitename}="@more";
    }
}
$"="";
####################################
# read and fixup the blacklist table
####################################

$blacklistsize = 0;
open(DAT,"$blacklist") || LogTxt( "cannot open $blacklist" );
while (<DAT>) {
  $blacklistsize++;
  $entry = $_;
  chomp($entry);
  $black{$entry} = 1;

  if (($entry !~ m/^www\./) and ($entry !~ /^\d+\.\d+\.\d+\.\d+$/)){
      # blacklist entry does not start with www. and is not a numerical IP address
      # add an extra entry in $black, with a prepended 'www.'
      $entry = 'www.' . $entry;
      $black{$entry} = 1;
  }
}
close(DAT);

##########################################
# Read the sites, which shall be 'crawled'
##########################################
$c=0;

if ($isWin) {
  $wget = 'c:\jesper\downloads\wget\wget.exe';
}
else {
  $wget = '/usr/local/bin/wget';
}

$totalSiteLinks = 0;      # Total number of links encountered from sites listed in
                          # sites.txt

$totalBlackListed = 0;    # Total number of blacklisted links

foreach $site (@site) {
  chomp $site;
  print "Before wget $site\n" if $linktest;
  LogTxt( "before wget $site" );
  @html = `$wget --output-document=- -q --timeout=$time_out $site`;
  print "after wget $site\n" if $linktest;
  LogTxt( "After wget $site" );

  $HTML="@html";

  @html=split(/<a/,$HTML);
  #print "<p> $site\n---------------------------\n\n";
  $numlink = 0;
  $blacklisted = 0;
  foreach $link (@html) {
      $numlink++;

      print "Raw link\n$link\nEnd of raw link\n" if $linktest;

      if ($link =~ /http:\/\/[^\:\"\']+\:[^\@]+\@[^ \"\']+/ix && $& !~ /(\?|cgi|bin|window\.)/i)
      {
        $link = $&;

        print "Matched link \n$link\n" if $linktest;

        $domain = getDomain( $link );
        #print "domain <$domain>\n";
        if (exists($black{$domain})) {
            $blacklisted++;
            print "Rejected by blacklist\n" if $linktest;
        }
        else {
            push(@links,"$link")
        }

        $c++;
      }
  }
  print "$numlink links from $site, blacklisted $blacklisted\n" if $linktest;
  LogTxt( "$numlink links from $site, blacklisted $blacklisted" );

  $totalSiteLinks  = $totalSiteLinks  + $numlink;
  $totalBlackListed = $totalBlackListed + $blacklisted;

}


#######################################
# Check for identical duplicates
#######################################

# Remove completely identical duplicates
foreach $link (@links) {
  if (exists($unique{$link})) {
      #print "double 1: discarded $link\n";
  }
  $unique{$link} = 1;
}

#########################################
# Check each link, that it actually works
#########################################


if ($supchk != 0) {
  print "Link checking suppressed\n";
}
else {

  # create list of links for wget, also create a hash, which allows us
  # to find the original password, when we process the results from wget. This
  # is necessary, since the wget output shows xxx's instead of the real passwords.

  open(CHK,">$chkfile") || LogTxt( "cannot open $chkfile" );
  $wgetNumber = 0;
  foreach $link (keys %unique) {
      $wgetNumber++;
      print CHK "$link\n";

      # save the original password in a hash, where we can
      # find it later
      $url  = getURL( $link );
      $user = getUser( $link );
      $pass = getPass( $link );
      $urluser2pass{$url}{$user} = $pass;

      print "Saving pass $pass for $url $user\n" if $savtest;
  }
  close(CHK);

  print "$wgetNumber links to check\n" if $wgtest;
  LogTxt( "Before checking $wgetNumber links" );
  if ($supwget == 0) {
      print "Now running wget for $wgetNumber links\n" if $wgtest;
      $wgetcommand = "$wget --spider --tries 2 --server-response " .
                    "--output-file=wgetresult.txt --timeout=5 --input-file=$chkfile";
      @wgetoutput = `$wgetcommand`;
      print "after wget\n" if $wgtest;
  }
  LogTxt( "After checking $wgetNumber links" );

  undef %unique; # Throw out all the links in preparation for the rebuild
                  # from wgetresult.txt

  # Read in the current redirection file
  if (open(REDIR, $redirfile)) {
      while (<REDIR>) {
        chomp;
        ($orgurl, $redirurl) = split(/\|/);
        $redirtable{$orgurl} = $redirurl;
      }
      close(REDIR);
  }

  open (RES, 'wgetresult.txt') || LogTxt( "could not open wgetresult.txt" );

  $redirurl = "";  # Start off with an empty redirect url
  $numchecked = 0;
  $numredir  = 0;

  while (<RES>) {
      if (/^--.+--  (.+)$/) {

        # First line in the attempt to check a page.
        # Obtain and save the URL.

        $link = $1;
        print "wgresult link = $link\n" if $wgtest;
      }
      elsif (/^HTTP request sent, awaiting response\.\.\. (\d\d\d)/) {

        # Line containing the HTTP status of a request
        # If the status is OK (200), and the URL being loaded is not the
        # latest Location: redirect URL, the URL is recorded in the unique table
        # as good and working.

        $httpstatus = $1;
        print "httpstatus = $httpstatus\n" if $wgtest;
        if ($httpstatus == 200) {
            if (($link ne $redirurl) && ($link ne ($redirurl . '/'))) {
              # This is OK, a good status and it was not the most recently
              # encountered Location: redirect url
              #
              # The link retrieved from wgetresult.txt has its password changed to
              # xxx's. This must now be repaired.

              $user = getUser( $link );
              $url  = getURL( $link );
              if (exists( $urluser2pass{$url}{$user} )) {
                  # Password found, build the proper link
                  $pass = $urluser2pass{$url}{$user};
                  $link = "http://$user:$pass\@$url";
                  print "final link $link\n" if $savtest;
              }
              else {
                  print "could not find password for \n$url\n$user\n" if $savtest;
              }

              $unique{$link} = 1;
              $numchecked++;
            }
            else {
              print "skipped due to redirection\n" if $wgtest;
            }
        }
      }
      elsif (/^\d+ Location: (.+)$/) {

        # This is a redirection HTTP response header. The URL is
        # recorded as the latest redirection URL, since WGET will try to
        # load it immediately, and we must ensure, that the potentially successful
        # loading of the redirect URL must not be recorded as a good link.

        $redirurl = $1;
        print "$link is redirected to $redirurl\n" if $wgtest;

        if (!exists($redirtable{$link})) {
            # A new unknown redirection, add to logfile
            open( LOG, ">>$logfile" );
            print LOG "$link is redirected to\n$redirurl\n\n";
            close(LOG);
        }
        $redirtable{$link} = $redirurl; # Record redirection in table
        $numredir++;
      }
     
  }
  close(RES);
  LogTxt( "After processing wgetresult.txt $numchecked links OK, $numredir redirections" );
  $workingLinks = $numchecked;
}

print "$numchecked links OK, $numredir redirections\n" if $wgtest;
$brokenLinks = $wgetNumber - $numchecked;

# Create a new version of the redirect table file

open(REDIR,">$redirfile") || LogTxt( "cannot open $redirfile" );
foreach $url (sort keys %redirtable) {
  print REDIR "$url|$redirtable{$url}\n";
}
close(REDIR);

############################################################################
# Add Fake (sponsor list), this is done after all the checks, so these links
# will be present, even if they perhaps don't work!
############################################################################

open(DAT,"$sponsor") || LogTxt( "cannot open $sponsor" );
@spons=<DAT>;
close(DAT);

$numSponsors = $#spons + 1;

LogTxt("Number of sponsor links: $numSponsors");

foreach $line (@spons) {
  chomp($line);
  $unique{$line} = 1;
}

# Throw out the original list so it can be reused
@links = ();

###################################################################
# Determine, which of the present links are new. Read in the result
# of the previous run from file links.txt, and make the comparison
###################################################################

if (open(PREV, $linksfile)) {
  while (<PREV>) {
      chomp;
      $prevlinks{$_} = 1;
  }
}

##########################
# Build list of alternates
##########################

foreach $line (sort cmpUrlNew keys %unique) {
  $url = getURL( $line );
  if (exists($uniqueURL{$url})) {
      #print "alternate link $line\n";
      push @{$alternates{$url}}, $line;  # $alternates{$url} is a list of the alternates
  }
  else {
      #print "link $line seen for the first time\n";
      $uniqueURL{$url} = 1;
      push(@links, $line);
  }
}


#########################################
@links=sort sortit @links;
$"="\n<p>";

$"="";

##################################
# Save the data, unless suppressed
##################################

if (!$suplink) {
  open(BOB,">$linksfile") || LogTxt( "cannot open $linksfile" );

  foreach $link (keys %unique) {
      print BOB "$link\n";
  }

  close(BOB);
}

#############################################################################
# Count number of unique links, not done above, since printing $linksfile can
# be suppressed
#############################################################################

$numchecked = 0;
foreach $link (keys %unique) {
  $numchecked++;
}

#######################################
# create the output files

$time=`/bin/date`;
if (!$time) { $time = 'Fri Jun  8 20:10:58 MST 2001'; }

# time format: Sat Apr  7 01:57:58 MST 2001


#######################################
# Make Pages

$PAGE="";
for($t=0,$c=0;$t<$#links-3;$t+=$max,$c++)
{
    $PAGE .="<a href=\"$page[$c]\" target=\"_self\">Page " .($c +1) ."</a> \n";
}
#######################################
$last="";

$c=0;
$p=0;
$total=$#links;
$count=0;

$newlinktext = 'NEW';


# Open final result output file, print header
open(PAGE,">$path$page[0]") || LogTxt( "cannot open $path$page[0]" );
&html("html/$head[0]","PAGE");


# Open the tables file
open(TABLES, "html/$tables") || LogTxt( "tables: cannot open <$tables>" );

LogTxt( "After opening $tables" );

$tabnum = 0;
$tabline = 0;

# Start off with empty table
$nexttable = '';
$linksInTable = 0;

foreach $line (@links) {
########################
# Get the Items

  $line =~ /http:\/\/([^\:]+)\:([^\@]+)\@([^\/]+)/i;
  $login=$1;
  $pass =$2;
  $sitename =$3;


  #print "<p> $line --> $login --> $pass --> $sitename";

  $sitename =~ s/(www|www1|www2|members)\.//ig;
  $sitename =~ s/\s//ig;
  $SO=$sitename;
 

############################################################
# stuff done toward printing it..
   
  $description=" No description";
  $description="$DESCRIPTION{$sitename}" if ($DESCRIPTION{$sitename});

  #print "<br>" .$links[$count+1] . " --> $SO \n";

  $url = getURL( $line );
  $domain = getDomain( $line );

  $altnum = 0; 

  $alternate = '';
  if (exists($alternates{$url})) {
      $totalt = $#{$alternates{$url}}; # Get number of alternates for this url

      foreach $alt (@{$alternates{$url}}) {
        $altnum++;
        $alternate = $alternate . "<a href=\"$alt\" target=\"_blank\">" .
                                  "<img src=\"Images/";

        # Use alternate_new if link didn't exist in the previous run
        if (!exists($prevlinks{$alt})) {
            $alternate = $alternate . "alternate_new.gif\"";
        }
        else {
            $alternate = $alternate . "alternate.gif\"";
        }

        $alternate = $alternate . " width=18 height=18 border=0></a>\n" ;
      }
  }
 

  if (($links[$count+1] =~ /$SO/i) && $c+1!=$max && $count+2 != $total ) {
      $des= "";
  }
  else {
      $des = $description;
  }   

  # Obtain rate and calculate average, if it exists
  if (exists($NUMVOTES{$domain})) {
      $numvotes = $NUMVOTES{$domain};
      $totalrate = $RATE{$domain};

      if ($totalrate != 0) {
        $avgrate = int(0.5 + $totalrate/$numvotes);
      }
      else {
        $avgrate = 0;
      }

      if ($numvotes == 1) {
        $numvotes = $numvotes . " vote";
      }
      else {
        $numvotes = $numvotes . " votes";
      }
  }
  else {
      $totalrate = 0;
      $avgrate = 0;
      $numvotes = '0 votes';
  }

  if (exists($prevlinks{$line})) {
      $newsite = '';
  }
  else {
      $newsite = $newlinktext;
  }

  if ($sitename) {
      $nexttable .= &html("html/entry.htm",'', 1);
      $linksInTable++;
      if ($linksInTable >= $numberOfLinksPerTable) {

        $tabnum++;
        LogTxt( "Starting generating table $tabnum" );

        # Read the skeleton of the next table
        $skeleton = '';
        while (defined($lin = <TABLES>)) {
            $tabline++;
            if (index( $lin, '<!-- END OF TABLE -->') >= 0) {
              last;
            }
            $skeleton .= $lin;
        }

        LogTxt( "Before printing table $tabnum" );

        eval("print PAGE <<BLOCK \n$skeleton\nBLOCK\n\n");


        $nexttable = '';
        $linksInTable = 0;
      }
  }

############################################################
  $count++;

}


# Print the remaining table rows to the next table

if ($linksInTable > 0) {

  LogTxt( "Starting generating last table" );
  # Read the skeleton of the next table
  $skeleton = '';
  while (defined($lin = <TABLES>)) {
      $tabline++;
      if (index( $lin, '<!-- END OF TABLE -->') >= 0) {
        last;
      }
      $skeleton .= $lin;
  }

  LogTxt( "Before printing last table" );
  eval("print PAGE <<BLOCK \n$skeleton\nBLOCK\n\n");
}

close(TABLES);

# Terminate the page by appending $foot

&html("html/$foot[0]","PAGE");

close(PAGE);

LogTxt( "End of crawler, $wgetNumber links checked, $numchecked links shown." );

# End of main program, below follows subroutines


sub sortit
{
  $aa=$a;$bb=$b;
  $aa =~ /http:\/\/([^\:]+)\:([^\@]+)\@([^\/]+)/ig;
  $aa=$sitename =$3;
  $bb =~ /http:\/\/([^\:]+)\:([^\@]+)\@([^\/]+)/ig;
  $bb=$sitename =$3;

  $aa =~ s/(www|www1|www2|members)\.//ig;
  $bb =~ s/(www|www1|www2|members)\.//ig;


 
return $aa cmp $bb;
}


# Comparison routine: Compares links. 'Old' links to an URL come before 'new' links to
#                                    same URL
sub cmpUrlNew
{
  my $urlA = getURL( $a );
  my $urlB = getURL( $b );
  my $retval;

  $retval = ($urlA cmp $urlB);        # Return 'highest' URL if different

  if ($retval == 0) {
      $retval = (exists($prevlinks{$b}) <=> exists($prevlinks{$a}));
  }
 
  return $retval;
}


sub getUser {
  my $link = shift;
  my $retValue;
  $retValue = $link;
  $retValue =~ s/\n//g;
  $retValue =~ s/http:\/\/(.*):(.*)\@(.*)$/$1/g;
  return $retValue;                                             
}#getUser

sub getPass {
  my $link = shift;
  my $retValue;
  $retValue = $link;
  $retValue =~ s/\n//g;
  $retValue =~ s/http:\/\/(.*):(.*)\@(.*)$/$2/g;
  return $retValue;                                             
}#getPass

sub getDomain {
  my $link = shift;
  my $retValue;
  $retValue = $link;
  $retValue =~ s/\n//g;
  $retValue =~ s/http:\/\/(.*):(.*)\@(.*)$/$3/g;;
  if ($retValue =~ /\s/) {
      $retValue =~ s/(.*)\s.*/$1/;
  }

  while ($retValue =~ /\//) {
      $retValue =~ s/^(.*)\/.*$/$1/;
  }

  return $retValue;
}#sub getDomain

sub getURL {
  my $link = shift;
  my $retValue;
  $retValue = $link;
  $retValue =~ s/\n//g;
  $retValue =~ s/http:\/\/(.*):(.*)\@(.*)$/$3/g;
  if ($retValue =~ /\s/) {
      $retValue =~ s/(.*)\s.*/$1/;
  }
  return $retValue;
}#getURL


sub checkLynxErrFile {
  my $errFile = shift;
  my $htmlCode = undef;
  my $htmlText = undef;

  open ERR, $errFile || LogTxt( "NO ERROR FILE $errFile FOUND" );
  @errFile = <ERR>;
  close ERR;

  #print "before errFile:\n";
  #print @errFile;
  #print "after errFile:\n";

  $errlines = @errFile;
  foreach $lin (@errFile) {
      chomp($lin);
      #print "errorline <$lin>\n";
      if ($lin =~ m/^STATUS=.+ (\d+) (.+)$/) {
        #print "HTML code <$1> text <$2>\n";
        $htmlCode = $1;
        $htmlText = $2;
      }
  }

  unlink $errFile;

  return ($htmlCode, $htmlText);
}

#################################
# Log text to file crawlerlog.txt
#################################

sub LogTxt {
  my ($txt) = @_;

  my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);

  open(LOG, ">>crawlerlog.txt");
  printf LOG "%04d-%02d-%02d %02d:%02d:%02d (%d) %s\n",  $year+1900, $mon+1, $mday,
                                                $hour, $min, $sec, $$, $txt;
  close(LOG);
}

Avatar billede edelbo Nybegynder
01. juli 2003 - 19:43 #1
Lukker!!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester