Vous devez être membre et vous identifier pour publier un article.
Les visiteurs peuvent toutefois commenter chaque article par une réponse.

BadLinksRecorder : récupérer et vérifier les liens d'un s

Astuces de l’Infobrol (Java)Article publié le 13/02/2007 12:48:23


Un superbe article de Emmanuel PUYBARET sur eTeks

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:.

le code



  1. /*
  2.  * BadLinksRecorder.java 1.0
  3.  *
  4.  * Copyright (c) 1999 Emmanuel PUYBARET - eTeks.
  5.  * All Rights Reserved.
  6.  *
  7.  */
  8.  
  9. import java.net.*;
  10. import java.io.*;
  11. import java.util.*;
  12. import java.text.*;
  13. import javax.swing.text.*;
  14. import javax.swing.text.html.*;
  15.  
  16. public class BadLinksRecorder
  17. {
  18. private URL searchedURL; // URL de départ
  19.  
  20. private Vector parsedHtmlFiles; // Ensemble des fichiers HTML lus
  21. private Vector otherCheckedFiles; // Ensemble des autre types de fichiers
  22. private Vector badFiles; // Ensemble des fichiers incorrects
  23.  
  24. private Hashtable htmlFiles; // Hashtable ayant pour clé une URL et
  25. // pour valeur les documents HTML lus
  26. private int badURLsCount; // Nombre de mauvaises URLs
  27. private int badAnchorsCount; // Nombre d'ancres non définies
  28.  
  29. public BadLinksRecorder (String searchedURL) throws IOException
  30. {
  31. this.searchedURL = new URL (searchedURL);
  32. // Tentative d'ouverture pour vérifier la validité de l'URL
  33. // Déclenchement d'une exception en cas de problème
  34. InputStream inputStream = getInputStream (this.searchedURL);
  35. inputStream.close ();
  36. }
  37.  
  38. private InputStream getInputStream (URL url) throws IOException
  39. {
  40. // Tentative d'ouverture du fichier
  41. URLConnection connection = url.openConnection ();
  42. // Si le fichier est accédé via le protocole http
  43. // vérification si un code 4xx n'a pas été renvoyé
  44. if ( connection instanceof HttpURLConnection
  45. && ((HttpURLConnection)connection).getResponseCode () / 100 == 4)
  46. throw new IOException ();
  47. return connection.getInputStream ();
  48. }
  49.  
  50. // Méthode d'interrogation des résultats du parsing
  51. public Vector getHTMLFiles ()
  52. {
  53. return parsedHtmlFiles;
  54. }
  55.  
  56. public Vector getMalformedURLs (URL file)
  57. {
  58. return ((HTMLBadLinks)htmlFiles.get (file)).getMalformedURLs ();
  59. }
  60.  
  61. public Vector getBadURLs (URL file)
  62. {
  63. return ((HTMLBadLinks)htmlFiles.get (file)).badURLs;
  64. }
  65.  
  66. public Vector getBadAnchors (URL file)
  67. {
  68. return ((HTMLBadLinks)htmlFiles.get (file)).badAnchors;
  69. }
  70.  
  71. public int getBadURLsCount ()
  72. {
  73. return badURLsCount;
  74. }
  75.  
  76. public int getBadAnchorsCount ()
  77. {
  78. return badAnchorsCount;
  79. }
  80.  
  81. // Parcours du fichier HTML donné au constructeur et de tous les fichiers
  82. // qui lui sont liés.
  83. public boolean parseFiles ()
  84. {
  85. parsedHtmlFiles = new Vector (); // Ensemble des fichiers HTML rencontrés
  86. otherCheckedFiles = new Vector (); // Ensemble des autre types de fichiers
  87. htmlFiles = new Hashtable ();
  88.  
  89. badFiles = new Vector ();
  90.  
  91. parsedHtmlFiles.addElement (searchedURL);
  92.  
  93. // Parcours de toutes les urls qui sont ajoutées à parsedHtmlFiles
  94. for (int i = 0; i ‹ parsedHtmlFiles.size (); i++)
  95. {
  96. URL searchURL = (URL)parsedHtmlFiles.elementAt (i);
  97. Reader urlReader = null;
  98. try
  99. {
  100. InputStream inputStream = getInputStream (searchURL);
  101. urlReader = new BufferedReader (
  102. new InputStreamReader (inputStream));
  103. }
  104. catch (IOException e)
  105. {
  106. // En cas d'échec, ajout à l'ensemble des mauvais fichiers
  107. badFiles.addElement (searchURL);
  108. continue;
  109. }
  110.  
  111. try
  112. {
  113. System.out.println ("Lecture de " + searchURL + "...");
  114.  
  115. // Création d'un document HTML ajouté à l'ensemble htmlFiles
  116. HTMLBadLinks doc = new HTMLBadLinks (searchURL, parsedHtmlFiles,
  117. otherCheckedFiles);
  118. htmlFiles.put (searchURL, doc);
  119.  
  120. // Démarrage de la lecture et du parsing du fichier HTML
  121. html.read (urlReader, doc, 0);
  122. urlReader.close ();
  123.  
  124. for (Enumeration e = doc.getURLs ().elements ();
  125. e.hasMoreElements (); )
  126. try
  127. {
  128. URL url = (URL)e.nextElement ();
  129. // Construction de l'URL sans ancre
  130. URL urlWithNoAnchor = new URL (url.getProtocol (), url.getHost (),
  131. url.getPort (), url.getFile ());
  132. String lowerCaseFile = url.getFile ().toLowerCase ();
  133. if ( lowerCaseFile.endsWith (".htm")
  134. || lowerCaseFile.endsWith (".html"))
  135. {
  136. // Si le fichier est un fichier HTML, ajout à l'ensemble
  137. // des fichiers HTML (vérification de l'extension en minuscules)
  138. if (!parsedHtmlFiles.contains (urlWithNoAnchor))
  139. parsedHtmlFiles.addElement (urlWithNoAnchor);
  140. }
  141. else
  142. // Pour les autres types de fichier (GIF, JPG,...), ajout
  143. // à l'ensemble des autres fichiers
  144. if (!otherCheckedFiles.contains (url))
  145. otherCheckedFiles.addElement (url);
  146. }
  147. catch (MalformedURLException exception)
  148. { } // Ne peut arriver
  149. }
  150. catch (IOException e)
  151. {
  152. System.out.println ("Probleme de lecture de " + searchURL);
  153. }
  154. { }
  155. }
  156.  
  157. // Suppression des mauvais fichiers de parsedHtmlFiles
  158. for (int i = 0; i ‹ parsedHtmlFiles.size (); )
  159. if (badFiles.contains (parsedHtmlFiles.elementAt (i)))
  160. parsedHtmlFiles.removeElementAt (i);
  161. else
  162. i++;
  163.  
  164. // Suppression des mauvais fichiers de otherCheckedFiles
  165. for (int i = 0; i ‹ otherCheckedFiles.size (); )
  166. {
  167. URL otherFile = (URL)otherCheckedFiles.elementAt (i);
  168. try
  169. {
  170. // Tentative d'ouverture du fichier
  171. InputStream inputStream = getInputStream (otherFile);
  172. inputStream.close ();
  173. i++;
  174. }
  175. catch (IOException e)
  176. {
  177. badFiles.addElement (otherFile);
  178. otherCheckedFiles.removeElementAt (i);
  179. }
  180. }
  181.  
  182. badURLsCount = 0;
  183. badAnchorsCount = 0;
  184.  
  185. // Recherche des URLs et ancres mauvaises dans tous les fichiers lus
  186. for (Enumeration e = htmlFiles.elements ();
  187. e.hasMoreElements (); )
  188. {
  189. HTMLBadLinks parsedDocument = (HTMLBadLinks)e.nextElement ();
  190. badURLsCount += parsedDocument.getMalformedURLs ().size ();
  191.  
  192. // Parcours de toutes les URLs du fichier
  193. for (Enumeration eURL = parsedDocument.getURLs ().elements ();
  194. eURL.hasMoreElements (); )
  195. try
  196. {
  197. URL url = (URL)eURL.nextElement ();
  198. // Construction de l'URL sans ancre
  199. URL urlWithNoAnchor = new URL (url.getProtocol (), url.getHost (),
  200. url.getPort (), url.getFile ());
  201. // Vérification si l'URL sans ancre est dans les mauvais fichiers
  202. if (badFiles.contains (urlWithNoAnchor))
  203. {
  204. parsedDocument.badURLs.addElement (urlWithNoAnchor);
  205. badURLsCount++;
  206. }
  207. else if ( !otherCheckedFiles.contains (url)
  208. && url.getRef () != null)
  209. {
  210. HTMLBadLinks htmlDocument = (HTMLBadLinks)htmlFiles.get (urlWithNoAnchor);
  211. // Recherche de l'existence de l'ancre dans le fichier indiqué
  212. if (!htmlDocument.getAnchors ().contains (url.getRef ()))
  213. {
  214. parsedDocument.badAnchors.addElement (url);
  215. badAnchorsCount++;
  216. }
  217. }
  218. }
  219. { } // Ne peut arriver
  220. }
  221.  
  222. // Tri bulle simple sur le vecteur parsedHtmlFiles
  223. // pour une sortie des fichiers par ordre alphabétique
  224. boolean sorted;
  225. do
  226. {
  227. sorted = true;
  228. for (int i = 0; i ‹ parsedHtmlFiles.size () - 1; i++)
  229. {
  230. URL url1 = (URL)parsedHtmlFiles.elementAt (i);
  231. URL url2 = (URL)parsedHtmlFiles.elementAt (i + 1);
  232. if (url1.toString ().compareTo (url2.toString ()) › 0)
  233. {
  234. parsedHtmlFiles.setElementAt (url2, i);
  235. parsedHtmlFiles.setElementAt (url1, i + 1);
  236. sorted = false;
  237. }
  238. }
  239. }
  240. while (!sorted);
  241.  
  242. // Renvoie true si pas d'erreur rencontrée
  243. return badURLsCount == 0 && badAnchorsCount == 0;
  244. }
  245.  
  246. // Classe dérivée de HTMLDocumentLinks qui mémorise en plus les URLs
  247. // et les ancres mauvaises
  248. private class HTMLBadLinks extends HTMLDocumentLinks
  249. {
  250. Vector badAnchors = new Vector ();
  251. Vector badURLs = new Vector ();
  252.  
  253. public HTMLBadLinks (URL file,
  254. Vector htmlFiles,
  255. Vector otherFiles)
  256. {
  257. super (file);
  258. }
  259. }
  260.  
  261. // Méthode main () d'exemple de mise en oeuvre
  262. // (prend en argument un nom de fichier HTML de départ
  263. // sous forme d'URL, par exemple file:/disk/dir1/index.html)
  264. public static void main (String args [])
  265. {
  266. try
  267. {
  268. BadLinksRecorder recorder = new BadLinksRecorder (args [0]);
  269. if (recorder.parseFiles ())
  270. System.out.println ("\nToutes les URL et ancres sont correctes.");
  271. else
  272. {
  273. // Pour chacun des fichiers HTML lus, listing des erreurs
  274. for (Enumeration e = recorder.getHTMLFiles ().elements ();
  275. e.hasMoreElements (); )
  276. {
  277. URL htmlFile = (URL)e.nextElement ();
  278. for (Enumeration e2 = recorder.getMalformedURLs (htmlFile).elements ();
  279. e2.hasMoreElements (); )
  280. System.out.println ( "Dans le fichier " + htmlFile
  281. + " l'URL " + e2.nextElement ()
  282. + " est incorrecte.");
  283. for (Enumeration e2 = recorder.getBadURLs (htmlFile).elements ();
  284. e2.hasMoreElements (); )
  285. System.out.println ( "Dans le fichier " + htmlFile
  286. + " l'URL " + e2.nextElement ()
  287. + " n'existe pas.");
  288. for (Enumeration e2 = recorder.getBadAnchors (htmlFile).elements ();
  289. e2.hasMoreElements (); )
  290. {
  291. URL url = (URL)e2.nextElement ();
  292. System.out.println ( "Dans le fichier " + htmlFile
  293. + " l'ancre" + url.getRef ()
  294. + " de l'URL " + url
  295. + " est inconnue.");
  296. }
  297. }
  298.  
  299. System.out.println ( "" + recorder.getBadURLsCount ()
  300. + " URL et " + recorder.getBadAnchorsCount ()
  301. + " ancres sont incorrectes.\n");
  302. }
  303.  
  304. // Liste de tous les fichiers HTML lus
  305. System.out.println ("\nListe des " + recorder.getHTMLFiles ().size () +
  306. " fichiers verifies :\n");
  307. for (Enumeration e = recorder.getHTMLFiles ().elements ();
  308. e.hasMoreElements (); )
  309. System.out.println (e.nextElement ());
  310. }
  311. catch (IOException e)
  312. {
  313. System.out.println ("Probleme d'acces a l'URL : " + args [0]);
  314. }
  315. }
  316. }


parseFiles



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 :

Elle parcourt dans une boucle l'ensemble des fichiers HTML mémorisés dans le vecteur parsedHtmlFiles. Ce vecteur ne contient au départ que l'URL passée au constructeur. A chaque tour de boucle, on essaye d'ouvrir un fichier HTML : Si l'ouverture échoue, l'URL du fichier est ajoutée au vecteur badFiles ; si elle réussit, une nouvelle instance de la classe HTMLBadLinks (qui dérive de HTMLDocumentLinks) est créée et l'ensemble des liens et des ancres de ce fichier est lu grâce à la méthode read ().
Parmi ces liens, tous ceux qui désignent des fichiers HTML et qui ne sont pas déjà dans le vecteur parsedHtmlFiles, sont ajoutés à la fin de parsedHtmlFiles, pour être lus plus tard. Ainsi tous les fichiers qui dépendent directement ou indirectement de l'URL de départ seront parcourus dans cette boucle.
Toutes les URLs des fichiers HTML inaccessibles sont enlevés du vecteur parsedHtmlFiles.
Chaque fichier non HTML (images, classes Java) du vecteur otherCheckedFiles est ouvert pour vérifier s'il existe ou non. S'il est inaccessible, son URL est retirée de otherCheckedFiles pour être ajoutée au vecteur badFiles.
Arrivé à ce point, cette méthode a mémorisé les trois ensembles d'URLs suivants :
L'ensemble parsedHtmlFiles des fichiers HTML existants. La table de hash htmlFiles mémorise le même ensemble en associant à chacune de ces URLs, une instance de la classe HTMLBadLinks. La classe HTMLBadLinks mémorise tous les liens et toutes les ancres d'un fichier HTML.
L'ensemble otherCheckedFiles des autres types de fichiers existants.
L'ensemble badFiles de tous les fichiers inaccessibles et référencés par les fichiers HTML.
Pour vérifier la cohérence des liens et des ancres de tous les fichiers HTML, il suffit alors de parcourir l'ensemble htmlFiles, en vérifiant que tous les liens de chacun des fichiers HTML sont corrects ou non.
Pour manipuler plus facilement l'ensemble parsedHtmlFiles, un tri bulle est effectué sur cet ensemble pour qu'il soit classé par ordre alphabétique.
Finalement, la méthode parseFiles () renvoie true ou false pour indiquer que tous les liens ou les ancres sont corrects ou non.
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.

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 :

Si vous utilisez Java 1.1 sous Windows et si vous avez installé Swing dans le répertoire c:\jdk\Swing-1.1, vous utiliserez la ligne de commande suivante :
javac -classpath c:\jdk\Swing-1.1\swing.jar;c:\jdk\lib\classes.zip BadLinksRecorder.java HTMLDocumentLinks.java

Si vous utilisez Java 2 dans lequel Swing est inclus, vous utiliserez la ligne de commande suivante :
javac BadLinksRecorder.java HTMLDocumentLinks.java


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...

Avatar :: Akira Sato Un article de Akira Sato

Source : www.eteks.com


Sélection, tri et recherche d'articles
FILTRER :
TRIER :1er critère : 2e critère :
CHERCHER : Dans les titres Dans le contenu


[Afficher les liens en fonction des critères du formulaire ci-dessus]

Nederlandse vertaling

U hebt gevraagd om deze site in het Nederlands te bezoeken. Voor nu wordt alleen de interface vertaald, maar nog niet alle inhoud.

Als je me wilt helpen met vertalingen, is je bijdrage welkom. Het enige dat u hoeft te doen, is u op de site registreren en mij een bericht sturen waarin u wordt gevraagd om u toe te voegen aan de groep vertalers, zodat u de gewenste pagina's kunt vertalen. Een link onderaan elke vertaalde pagina geeft aan dat u de vertaler bent en heeft een link naar uw profiel.

Bij voorbaat dank.

Document heeft de 13/09/2004 gemaakt, de laatste keer de 26/10/2018 gewijzigd
Bron van het afgedrukte document:https://www.gaudry.be/nl/ast-rf-387.html

De infobrol is een persoonlijke site waarvan de inhoud uitsluitend mijn verantwoordelijkheid is. De tekst is beschikbaar onder CreativeCommons-licentie (BY-NC-SA). Meer info op de gebruiksvoorwaarden en de auteur.