Analizando HTML en Bash

Contenidos

Bash Shell

Tengo un procedimiento en el que necesito copiar todas las imágenes de una página web. Solía ​​ejecutar este procedimiento con xmllint, que procesará un archivo XML o HTML e imprimirá las entradas que especifique. Pero cuando mi proveedor de host de servidor actualizó sus sistemas, no incluyeron xmllint. Entonces tuve que hallar otra manera de extraer una lista de imágenes de una página HTML. Resulta que puedes hacer esto en Bash.

Puede que no crea que Bash pueda analizar archivos de datos, pero puede hacerlo con un pensamiento inteligente. Bash, del mismo modo que otros shells de UNIX anteriores, puede analizar las líneas de una en una desde un archivo a través de la función incorporada read declaración.

Por defecto, el read declaración escanea una línea de datos y la divide en campos. De forma general, read divide los campos usando espacios y tabulaciones, con nuevas líneas al final de cada línea, pero puede cambiar esta conducta configurando el Separador de campo interno (IFS) valor y el delimitador de final de línea (-d).

Para analizar un archivo HTML usando read , selecciona el IFS a un símbolo mayor que (>) y el delimitador a un símbolo menor que (<). Cada vez que Bash escanea una línea, analiza hasta la próxima < (el comienzo de una etiqueta HTML) después divide esos datos en cada > (el final de una etiqueta HTML). Este código de muestra toma una línea de entrada y divide los datos en TAG y VALUE variables:

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

Exploremos cómo funciona esto. Considere este simple archivo HTML:

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

La primera vez read analiza este archivo, se detiene en el primer < símbolo. Puesto que < es el primer carácter de esta entrada de muestra, lo que significa que Bash encuentra una cadena vacía. La resultante TAG y VALUE las cadenas además están vacías. Pero eso está bien para mi caso de uso.

La próxima vez que Bash lee la entrada, obtiene img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" />↲ con una nueva línea justo antes de la alt, y se detiene antes de la < símbolo en la próxima línea. Después read divide la línea en el > símbolo, que deja TAG con img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" / y VALUE con una nueva línea vacía.

La tercera vez read analiza el archivo HTML, obtiene p>some text. Bash divide la cuerda en el > Resultando en TAG conteniendo p y VALUE con some text .

Ahora que comprendes cómo utilizar read, es fácil analizar un archivo HTML más largo con Bash. Comience con una función Bash llamada xmlgetnext para analizar los datos usando read , dado que lo hará una y otra vez en el guión. Nombré mi función xmlgetnext para recordarme que este es un reemplazo para Linux xmllint programa, pero podría haberlo llamado con la misma facilidad htmlgetnext .

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

Ahora llama a eso xmlgetnext función para analizar el archivo HTML. Esta es mi completa htmltags texto:

#!/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 última línea es la clave. Recorre el archivo usando xmlgetnext para analizar el HTML e imprime solo el TAG entradas. Y por como echo opera con los separadores de campo estándar, cualquier línea como img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" / que contienen una nueva línea se imprimen en una sola línea, como img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png" alt="My logo" /.

Para obtener solo la lista de imágenes, ejecuto la salida de este script a través de grep para imprimir solo las líneas que disponen un img etiqueta al comienzo de la línea.

Suscribite a nuestro Newsletter

No te enviaremos correo SPAM. Lo odiamos tanto como tú.