Agence web » Actualités du digital » Analyser du HTML dans Bash – CloudSavvy IT

Analyser du HTML dans Bash – CloudSavvy IT

J’ai un processus où 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.

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 le read déclaration.

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

Pour analyser un fichier HTML en utilisant read , met le IFS à un symbole supérieur à (>) et le délimiteur à un symbole inférieur à (<). Chaque fois que Bash scanne une ligne, il analyse jusqu’à la suivante < (le début d’une balise HTML) puis divise 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 dans le TAG et VALUE variables :

local IFS='>'
read -d '<' TAG VALUE

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

<img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"
alt="My logo" />
<p>some text</p>

La première fois 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. La résultante TAG et VALUE les chaînes sont également vides. Mais c’est bien pour mon cas d’utilisation.

La prochaine fois que Bash lit l’entrée, il obtient img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" />↲ avec une nouvelle ligne juste avant l’alt, et s’arrête avant le < symbole sur la ligne suivante. Puis read divise la ligne au > symbole, qui laisse TAG avec img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" / et VALUE avec une nouvelle ligne vide.

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

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 en utilisant read , puisque vous le ferez encore et encore dans le script. j’ai nommé ma fonction xmlgetnext pour me rappeler que c’est un remplacement pour Linux xmllint programme, mais j’aurais pu tout aussi bien le nommer htmlgetnext .

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

Maintenant appelle ça xmlgetnext fonction pour analyser le fichier HTML. C’est mon complet htmltags scénario:

#!/bin/sh
# print a list of all html tags

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

cat $1 | while xmlgetnext ; do echo $TAG ; done

La dernière ligne est la clé. Il parcourt le fichier en utilisant xmlgetnext pour analyser le HTML et n’imprime que le TAG entrées. Et à cause de comment echo fonctionne avec les séparateurs de champs standard, toutes les lignes comme img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" / qui contiennent un saut de ligne sont imprimés sur une seule ligne, comme img src="https://www.cloudsavvyit.com/8315/parsing-html-in-bash/logo.png" alt="My logo" /.

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 un img balise au début de la ligne.

★★★★★