Analyser du HTML dans Bash

0
62

J'ai un processus dans lequel je dois copier toutes les images d'une page Web. J'avais l'habitude d'exécuter ce processus avec xmllint, qui traitera un fichier XML ou HTML et imprimera les entrées que vous spécifiez. Mais lorsque mon fournisseur d'hébergement de serveur a mis à niveau ses systèmes, il n'a pas inclus xmllint. J'ai donc dû trouver un autre moyen d'extraire une liste d'images d'une page HTML. Il s'avère que vous pouvez le faire dans Bash.

L'instruction read

Vous ne pensez peut-être pas que Bash peut analyser des fichiers de données, mais il le peut avec une réflexion intelligente. Bash, comme les autres shells UNIX avant lui, peut analyser les lignes une par une à partir d'un fichier via l'instruction read intégrée.

Par défaut, l'instruction read analyse une ligne de données et la divise en champs. Habituellement, read divise les champs à l'aide d'espaces et de tabulations, avec des retours à la ligne terminant chaque ligne, mais vous pouvez modifier ce comportement en définissant la valeur du séparateur de champs interne (IFS) et le délimiteur de fin de ligne (-d).

< p>Pour analyser un fichier HTML à l'aide de read , définissez l'IFS sur un symbole supérieur à (>) et le délimiteur sur un symbole inférieur à (<). Chaque fois que Bash scanne une ligne, il analyse jusqu'à la prochaine < (le début d'une balise HTML) sépare ensuite ces données à chaque > (la fin d'une balise HTML). Cet exemple de code prend une ligne d'entrée et divise les données en variables TAG et VALUE :

local IFS='>' lire -d '<' VALEUR DU TAG

Voyons comment cela fonctionne. Considérez ce simple fichier HTML :

<img src=”logo.png” alt=”Mon logo” /> <p>du texte</p> Publicité

La première fois que read analyse ce fichier, il s'arrête au premier < symbole. Depuis ≪ est le premier caractère de cet exemple d'entrée, ce qui signifie que Bash trouve une chaîne vide. Les chaînes TAG et VALUE résultantes sont également vides. Mais c'est parfait pour mon cas d'utilisation.

La prochaine fois que Bash lit l'entrée, il obtient img src=”logo.png”↲alt=”Mon logo” />↲ avec un saut de ligne juste avant l'alt et s'arrête avant le < symbole sur la ligne suivante. Ensuite, read divise la ligne au niveau de > symbole, qui laisse TAG avec img src=”logo.png”↲alt=”Mon logo”/et VALUE avec une nouvelle ligne vide.

La troisième fois que read analyse le fichier HTML, il obtient p>du texte. Bash divise la chaîne au niveau de > résultant en un TAG contenant p et VALUE avec du texte.

Un analyseur simple

Maintenant que vous comprenez comment utiliser read, il est facile d'analyser un fichier HTML plus long avec Bash. Commencez par une fonction Bash appelée xmlgetnext pour analyser les données à l'aide de read , car vous le ferez encore et encore dans le script. J'ai nommé ma fonction xmlgetnext pour me rappeler qu'il s'agit d'un remplacement du programme Linux xmllint, mais j'aurais pu tout aussi bien la nommer htmlgetnext .

xmlgetnext () { local IFS='>' lire -d '<' TAG VALUE }

Appelez maintenant cette fonction xmlgetnext pour analyser le fichier HTML. Ceci est mon script htmltags complet :

#!/bin/sh # affiche une liste de toutes les balises html xmlgetnext () { local IFS='>' lire -d '<' VALEUR DE L'ÉTIQUETTE } chat $1 | tandis que xmlgetnext ; faire echo $TAG ; done

La dernière ligne est la clé. Il parcourt le fichier en utilisant xmlgetnext pour analyser le code HTML et n'imprime que les entrées TAG. Et à cause de la façon dont echo fonctionne avec les séparateurs de champs standard, toutes les lignes comme img src=”logo.png”↲alt=”Mon logo”/qui contiennent une nouvelle ligne sont imprimées sur une seule ligne, comme img src=”logo.png ” alt=”Mon logo” /.

Analyse HTML dans Bash

Publicité

Pour récupérer uniquement la liste des images, j'exécute la sortie de ce script via grep pour n'imprimer que les lignes qui ont une balise img au début de la ligne.