Analisando HTML no Bash

Conteúdo

Bash Shell

Tenho um procedimento em que preciso copiar todas as imagens de uma página da web. Eu costumava executar este procedimento com xmllint, que irá processar um arquivo XML ou HTML e imprimir as entradas que você especificar. Mas quando meu provedor de host de servidor atualizou seus sistemas, eles não incluíram xmllint. Então, eu tive que encontrar outra maneira de extrair uma lista de imagens de uma página HTML. Acontece que você pode fazer isso no bash.

Você pode não pensar que o Bash pode analisar arquivos de dados, mas você pode fazer isso com pensamento inteligente. Bash, da mesma forma que outros shells UNIX anteriores, você pode analisar as linhas uma a uma de um arquivo através da função embutida read demonstração.

Por padrão, a read declaração varre uma linha de dados e os divide em campos. Geralmente, read dividir os campos usando espaços e tabulações, com novas linhas no final de cada linha, mas você pode mudar este comportamento configurando o Separador de Campo Interno (IFS) valor e o delimitador de fim de linha (-d).

Para analisar um arquivo HTML usando read , selecione os 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 e VALUE variáveis:

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, pára no primeiro < símbolo. Sendo que < é o primeiro caractere deste exemplo de entrada, o que significa que o Bash encontra uma string vazia. O resultado TAG e VALUE as correntes também estão vazias. Mas isso é bom para o meu caso de uso.

Da próxima vez que o Bash ler a entrada, pegue img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" />↲ com uma nova linha antes do alt, e para antes < símbolo na próxima linha. Depois de read divide a linha no > símbolo, o que sai TAG com img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" / e VALUE com uma nova linha vazia.

O terceiro tempo read analise o arquivo HTML, pegue p>some text. Bash divide a corda no > Resultando em TAG contendo p e VALUE com 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
}

gato $1 | while xmlgetnext ; do echo $TAG ; feito

La última línea es la clave. Percorra o arquivo usando xmlgetnext para analisar o HTML e imprimir apenas o TAG ingressos. E para como echo opera com separadores de campo padrão, qualquer linha como img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png"↲alt="My logo" / contendo uma nova linha são impressos em uma única linha, O que img src="https://www.systempeaker.com/8315/parsing-html-in-bash/logo.png" alt="My logo" /.

Para obter apenas a lista de imagens, Eu executo a saída deste script por meio de grep para imprimir apenas linhas que tenham um img etiqueta no início da linha.

Assine a nossa newsletter

Nós não enviaremos SPAM para você. Nós odiamos isso tanto quanto você.