Tenho um processo em que preciso copiar todas as imagens de uma página da web. Eu costumava executar esse processo com xmllint, que processa um arquivo XML ou HTML e imprime as entradas que você especificar. Mas quando meu provedor de host de servidor atualizou seus sistemas, eles não incluíram o xmllint. Então, 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 achar que o Bash não pode analisar arquivos de dados, mas pode com um pensamento inteligente. O Bash, como outros shells UNIX anteriores, pode analisar as linhas uma de cada vez de um arquivo por meio da instrução de leitura integrada.
Por padrão, a instrução read varre uma linha de dados e os divide em campos. Normalmente, a leitura divide os campos usando espaços e tabulações, com novas linhas terminando cada linha, mas você pode alterar esse comportamento definindo o valor do Separador de campo interno (IFS) e o delimitador de fim de linha (-d).
Para analisar um arquivo HTML usando leitura, defina o IFS como um símbolo maior que (>) e o delimitador como um símbolo menor que (<). Cada vez que o Bash verifica uma linha, ele analisa até a próxima < (o início de uma tag HTML) então divide esses dados em cada > (o fim de uma tag HTML). Este código de amostra pega uma linha de entrada e divide os dados nas variáveis TAG e VALUE:
IFS local = '>' ler -d '<' VALOR DA TAG
Vamos explorar como isso funciona. Considere este arquivo HTML simples:
< img src = "https://comofazergeek.blogspot.com/2021/09/logo.%20png" alt = "Meu logotipo" / > < p > algum texto < / p >
Publicidade
A primeira vez que a leitura analisa este arquivo, ela para na primeira < símbolo. Uma vez que < é o primeiro caractere dessa entrada de amostra, o que significa que o Bash encontra uma string vazia. As strings TAG e VALUE resultantes também estão vazias. Mas isso é bom para o meu caso de uso.
Na próxima vez que o Bash ler a entrada, ele obterá img src = "https://comofazergeek.blogspot.com/2021/09/logo.%20png" ↲alt = "Meu logotipo" / > ↲ com uma nova linha logo antes do alt, e pára antes do < símbolo na próxima linha. Em seguida, ler divide a linha na seção > símbolo, que deixa TAG com img src = "https://comofazergeek.blogspot.com/2021/09/logo.%20png" ↲alt = "Meu logotipo" / e VALUE com uma nova linha vazia.
Na terceira vez que a leitura analisa o arquivo HTML, ele obtém p > algum texto. O Bash divide a string no ponto > resultando em TAG contendo pe VALUE com algum texto.
Agora que você sabe como usar a leitura, é fácil analisar um arquivo HTML mais longo com o Bash. Comece com uma função Bash chamada xmlgetnext para analisar os dados usando read, uma vez que você fará isso repetidamente no script. Chamei minha função de xmlgetnext para me lembrar que esta é uma substituição para o programa xmllint do Linux, mas eu poderia facilmente chamá-la de htmlgetnext.
xmlgetnext () {IFS local = '>' ler -d '<' VALOR DE TAG}
Agora chame a função xmlgetnext para analisar o arquivo HTML. Este é meu script htmltags completo:
#! / bin / sh # imprime uma lista de todas as tags html xmlgetnext () {local IFS = '>' ler -d '<' VALOR DA TAG} cat $ 1 | while xmlgetnext; echo $ TAG; feito
A última linha é a chave. Ele percorre o arquivo usando xmlgetnext para analisar o HTML e imprime apenas as entradas TAG. E por causa de como echo opera com os separadores de campo padrão, quaisquer linhas como img src = "https://comofazergeek.blogspot.com/2021/09/logo.%20png" ↲alt = "Meu logotipo" / que contêm uma nova linha são impressas em uma única linha, como img src = "https://comofazergeek.blogspot.com/2021/09/logo.%20png "alt =" Meu logotipo "/.
Analisando HTML no Bash
Publicidade
Para buscar apenas a lista de imagens, executo a saída deste script por meio do grep para imprimir apenas as linhas que têm uma tag img no início da linha.