Page d'accueilFindIt !ContactAstuces JavaAstuces Java

Astuces JavaTM

Astuces Java

Tip

 Vérifier les liens et les ancres d'un site Internet

 

Niveau : initié
Compatibilité : Java 1.1 + Swing 1.1 ou Java 2

Contexte

L'astuce précédente vous a présenté la classe HTMLDocumentLinks qui permet de récupérer la liste des liens et des ancres d'un fichier HTML.
Dans la suite de cette astuce, voici le programme BadLinksRecorder vérifiant si tous les liens et les ancres utilisées dans l'ensemble des fichiers HTML d'un site Internet sont valides. Ce programme vous donne en sortie la liste de tous les liens et toutes les ancres qui sont incorrectes, afin que vous puissiez les corriger.
Voici la liste des types de liens dont ce programme vérifie la validité :

Rappel : si vous utilisez Java 1.1, vous devez té7lécharger Swing 1.1 à l'adresse (Swing 1.1 est inclus dans Java 2) :
http://java.sun.com/products/jfc/download.html.

Programme BadLinksRecorder

La classe BadLinksRecorder qui suit, permet de lire et de gérer l'ensemble des fichiers d'un site Internet (fichiers HTML, images, classes Java). Son constructeur prend en paramètre l'URL d'un fichier HTML qui est utilisée par la classe comme point de départ pour retrouver tous les fichiers dépendant directement ou indirectement de cette URL.
Tous les liens vers des fichiers qui ne sont pas relatifs à l'URL de départ sont ignorés, mais en modifiant la méthode ignoreURL () de la classe HTMLDocumentLinks, vous pouvez changer cette contrainte.
Tous les fichiers sont manipulés sous forme d'URL ce qui permet d'accéder aussi bien à des fichiers sur un disque local avec le protocole file: ou sur des fichiers accessibles sur Internet par le protocole http:.

La méthode principale de cette classe est parseFiles (). Bien que longue, elle effectue un ensemble d'opérations assez simples, dont voici la description :

La méthode main () de la classe BadLinksRecorder prend en paramètre une URL. Cette URL est utilisée comme point de départ pour vérifier l'ensemble d'un site Internet et doit contenir des liens vers les autres fichiers du site. Typiquement, cette URL est le fichier d'index du site.
Après avoir créé une instance de BadLinksRecorder, et appelé la methode parseFiles (), la méthode main () imprime sur la sortie standard la liste de tous les liens et toutes les ancres qui sont incorrectes, suivie de la liste des fichiers HTML vérifiés.

 

 /*
 * BadLinksRecorder.java  1.0
 *
 * Copyright (c) 1999 Emmanuel PUYBARET - eTeks.
 * All Rights Reserved.
 *
 */
 
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
 
public class BadLinksRecorder
{
  private URL       searchedURL;       // URL de départ
 
  private Vector    parsedHtmlFiles;   // Ensemble des fichiers HTML lus
  private Vector    otherCheckedFiles; // Ensemble des autre types de fichiers
  private Vector    badFiles;          // Ensemble des fichiers incorrects
 
  private Hashtable htmlFiles;         // Hashtable ayant pour clé une URL et
                                       // pour valeur les documents HTML lus
  private int       badURLsCount;      // Nombre de mauvaises URLs
  private int       badAnchorsCount;   // Nombre d'ancres non définies
 
  public BadLinksRecorder (String searchedURL) throws IOException
  {
    this.searchedURL = new URL (searchedURL);
    // Tentative d'ouverture pour vérifier la validité de l'URL
    // Déclenchement d'une exception en cas de problème
    InputStream inputStream = getInputStream (this.searchedURL);
    inputStream.close ();
  }
 
  private InputStream getInputStream (URL url) throws IOException
  {
    // Tentative d'ouverture du fichier
    URLConnection connection = url.openConnection ();
    // Si le fichier est accédé via le protocole http
    // vérification si un code 4xx n'a pas été renvoyé
    if (   connection instanceof HttpURLConnection
        && ((HttpURLConnection)connection).getResponseCode () / 100 == 4)
      throw new IOException ();
    return connection.getInputStream ();
  }
 
  // Méthode d'interrogation des résultats du parsing
  public Vector getHTMLFiles ()
  {
    return parsedHtmlFiles;
  }
 
  public Vector getMalformedURLs (URL file)
  {
    return ((HTMLBadLinks)htmlFiles.get (file)).getMalformedURLs ();
  }
 
  public Vector getBadURLs (URL file)
  {
    return ((HTMLBadLinks)htmlFiles.get (file)).badURLs;
  }
 
  public Vector getBadAnchors (URL file)
  {
    return ((HTMLBadLinks)htmlFiles.get (file)).badAnchors;
  }
 
  public int getBadURLsCount ()
  {
    return badURLsCount;
  }
 
  public int getBadAnchorsCount ()
  {
    return badAnchorsCount;
  }
 
  // Parcours du fichier HTML donné au constructeur et de tous les fichiers
  // qui lui sont liés.
  public boolean parseFiles ()
  {
    parsedHtmlFiles   = new Vector (); // Ensemble des fichiers HTML rencontrés
    otherCheckedFiles = new Vector (); // Ensemble des autre types de fichiers
    htmlFiles         = new Hashtable ();
 
    badFiles          = new Vector ();
 
    parsedHtmlFiles.addElement (searchedURL);
 
    // Parcours de toutes les urls qui sont ajoutées à parsedHtmlFiles
    HTMLEditorKit  html = new HTMLEditorKit ();
    for (int i = 0; i < parsedHtmlFiles.size (); i++)
    {
      URL    searchURL = (URL)parsedHtmlFiles.elementAt (i);
      Reader urlReader = null;
      try
      {
        InputStream inputStream = getInputStream (searchURL);
        urlReader = new BufferedReader (
                      new InputStreamReader (inputStream));
      }
      catch (IOException e)
      {
        // En cas d'échec, ajout à l'ensemble des mauvais fichiers
        badFiles.addElement (searchURL);
        continue;
      }
 
      try
      {
        System.out.println ("Lecture de " + searchURL + "...");
 
        // Création d'un document HTML ajouté à l'ensemble htmlFiles
        HTMLBadLinks doc = new HTMLBadLinks (searchURL, parsedHtmlFiles,
                                             otherCheckedFiles);
        htmlFiles.put (searchURL, doc);
 
        // Démarrage de la lecture et du parsing du fichier HTML
        html.read (urlReader, doc, 0);
        urlReader.close ();
 
        for (Enumeration e = doc.getURLs ().elements ();
             e.hasMoreElements (); )
          try
          {
            URL url = (URL)e.nextElement ();
            // Construction de l'URL sans ancre
            URL urlWithNoAnchor = new URL (url.getProtocol (), url.getHost (),
                                           url.getPort (), url.getFile ());
            String lowerCaseFile = url.getFile ().toLowerCase ();
            if (   lowerCaseFile.endsWith (".htm")
                || lowerCaseFile.endsWith (".html"))
            {
              // Si le fichier est un fichier HTML, ajout à l'ensemble
              // des fichiers HTML (vérification de l'extension en minuscules)
              if (!parsedHtmlFiles.contains (urlWithNoAnchor))
                parsedHtmlFiles.addElement (urlWithNoAnchor);
            }
            else
              // Pour les autres types de fichier (GIF, JPG,...), ajout
              // à l'ensemble des autres fichiers
              if (!otherCheckedFiles.contains (url))
                otherCheckedFiles.addElement (url);
          }
          catch (MalformedURLException exception)
          { } // Ne peut arriver
      }
      catch (IOException e)
      {
        System.out.println ("Probleme de lecture de " + searchURL);
      }
      catch (BadLocationException e)
      { }
    }
 
    // Suppression des mauvais fichiers de parsedHtmlFiles
    for (int i = 0; i < parsedHtmlFiles.size (); )
      if (badFiles.contains (parsedHtmlFiles.elementAt (i)))
        parsedHtmlFiles.removeElementAt (i);
      else
        i++;
 
    // Suppression des mauvais fichiers de otherCheckedFiles
    for (int i = 0; i < otherCheckedFiles.size (); )
    {
      URL otherFile = (URL)otherCheckedFiles.elementAt (i);
      try
      {
        // Tentative d'ouverture du fichier
        InputStream inputStream = getInputStream (otherFile);
        inputStream.close ();
        i++;
      }
      catch (IOException e)
      {
        badFiles.addElement (otherFile);
        otherCheckedFiles.removeElementAt (i);
      }
    }
 
    badURLsCount    = 0;
    badAnchorsCount = 0;
 
    // Recherche des URLs et ancres mauvaises dans tous les fichiers lus
    for (Enumeration e = htmlFiles.elements ();
         e.hasMoreElements (); )
    {
      HTMLBadLinks parsedDocument = (HTMLBadLinks)e.nextElement ();
      badURLsCount += parsedDocument.getMalformedURLs ().size ();
 
      // Parcours de toutes les URLs du fichier
      for (Enumeration eURL = parsedDocument.getURLs ().elements ();
           eURL.hasMoreElements (); )
        try
        {
          URL url = (URL)eURL.nextElement ();
          // Construction de l'URL sans ancre
          URL urlWithNoAnchor = new URL (url.getProtocol (), url.getHost (),
                                         url.getPort (), url.getFile ());
          // Vérification si l'URL sans ancre est dans les mauvais fichiers
          if (badFiles.contains (urlWithNoAnchor))
          {
            parsedDocument.badURLs.addElement (urlWithNoAnchor);
            badURLsCount++;
          }
          else if (   !otherCheckedFiles.contains (url)
                   && url.getRef () != null)
          {
            HTMLBadLinks htmlDocument = (HTMLBadLinks)htmlFiles.get (urlWithNoAnchor);
            // Recherche de l'existence de l'ancre dans le fichier indiqué
            if (!htmlDocument.getAnchors ().contains (url.getRef ()))
            {
              parsedDocument.badAnchors.addElement (url);
              badAnchorsCount++;
            }
          }
        }
        catch (MalformedURLException ex)
        { } // Ne peut arriver
    }
 
    // Tri bulle simple sur le vecteur parsedHtmlFiles
    // pour une sortie des fichiers par ordre alphabétique
    boolean sorted;
    do
    {
      sorted = true;
      for (int i = 0; i < parsedHtmlFiles.size () - 1; i++)
      {
        URL url1 = (URL)parsedHtmlFiles.elementAt (i);
        URL url2 = (URL)parsedHtmlFiles.elementAt (i + 1);
        if (url1.toString ().compareTo (url2.toString ()) > 0)
        {
          parsedHtmlFiles.setElementAt (url2, i);
          parsedHtmlFiles.setElementAt (url1, i + 1);
          sorted = false;
        }
      }
    }
    while (!sorted);
 
    // Renvoie true si pas d'erreur rencontrée
    return badURLsCount == 0 && badAnchorsCount == 0;
  }
 
  // Classe dérivée de HTMLDocumentLinks qui mémorise en plus les URLs
  // et les ancres mauvaises
  private class HTMLBadLinks extends HTMLDocumentLinks
  {
    Vector badAnchors = new Vector ();
    Vector badURLs    = new Vector ();
 
    public HTMLBadLinks (URL    file,
                         Vector htmlFiles,
                         Vector otherFiles)
    {
      super (file);
    }
  }
  
  // Méthode main () d'exemple de mise en oeuvre 
  // (prend en argument un nom de fichier HTML de départ  
  // sous forme d'URL, par exemple file:/disk/dir1/index.html)
  public static void main (String args [])
  {
    try
    {
      BadLinksRecorder recorder = new BadLinksRecorder (args [0]);
      if (recorder.parseFiles ())
        System.out.println ("\nToutes les URL et ancres sont correctes.");
      else
      {
        // Pour chacun des fichiers HTML lus, listing des erreurs
        for (Enumeration e = recorder.getHTMLFiles ().elements ();
             e.hasMoreElements (); )
        {
          URL htmlFile = (URL)e.nextElement ();
          for (Enumeration e2 = recorder.getMalformedURLs (htmlFile).elements ();
               e2.hasMoreElements (); )
            System.out.println (  "Dans le fichier " + htmlFile 
                                + " l'URL " + e2.nextElement () 
                                + " est incorrecte.");
          for (Enumeration e2 = recorder.getBadURLs (htmlFile).elements ();
               e2.hasMoreElements (); )
            System.out.println (  "Dans le fichier " + htmlFile 
                                + " l'URL " + e2.nextElement () 
                                + " n'existe pas.");
          for (Enumeration e2 = recorder.getBadAnchors (htmlFile).elements ();
               e2.hasMoreElements (); )    
          {
            URL url = (URL)e2.nextElement ();
            System.out.println (  "Dans le fichier " + htmlFile 
                                + " l'ancre" + url.getRef ()
                                + " de l'URL " + url
                                + " est inconnue.");
          }
        }
 
        System.out.println (  "" + recorder.getBadURLsCount ()
                            + " URL et " + recorder.getBadAnchorsCount () 
                            + " ancres sont incorrectes.\n");
      }    
      
      // Liste de tous les fichiers HTML lus
      System.out.println ("\nListe des " + recorder.getHTMLFiles ().size () + 
                          " fichiers verifies :\n");
      for (Enumeration e = recorder.getHTMLFiles ().elements ();
           e.hasMoreElements (); )
        System.out.println (e.nextElement ());
    }  
    catch (IOException e)
    {
      System.out.println ("Probleme d'acces a l'URL : " + args [0]);
    }
  }      
}

Compilation

Pour utiliser le programme précédent, recopiez les programmes BadLinksRecorder.java et HTMLDocumentLinks.java, puis compilez-les d'une des manières suivantes :

Exécution

L'exemple de ce programme prend en paramètre l'URL du fichier HTML de base d'un site Internet (situé localement ou sur un serveur HTTP).

Si vous utilisez Java 2, vous pouvez exécuter le programme avec par exemple, la ligne de commande suivante :
java BadLinksRecorder http://www.unsite.com/index.html

Attention ! Tous les fichiers dont l'URL est relative à l'URL de départ seront lus qu'ils dépendent directement ou indirectement (via d'autres fichiers) du fichier HTML de base. Ceci peut représenté pour les gros sites une très grande quantité d'information longue à lire et à traiter...


Page d'accueilFindIt !ContactAstuces JavaAstuces JavaDébut de la page
© Copyrights 1997-2023 Emmanuel PUYBARET / eTeks
- Tous droits réservés -
Astuces Java