HTML ontleden in Bash

0
171

Ik heb een proces waarbij ik alle afbeeldingen van een web moet kopiëren bladzijde. Ik heb dit proces altijd uitgevoerd met xmllint, dat een XML- of HTML-bestand zal verwerken en de door u opgegeven vermeldingen zal afdrukken. Maar toen mijn serverhost-provider hun systemen opwaardeerde, bevatten ze geen xmllint. Dus moest ik een andere manier vinden om een ​​lijst met afbeeldingen uit een HTML-pagina te halen. Het blijkt dat je dit in Bash kunt doen.

De gelezen verklaring

Je denkt misschien niet dat Bash gegevensbestanden kan ontleden, maar met wat slim nadenken kan het. Bash kan, net als andere UNIX-shells ervoor, regels één voor één ontleden uit een bestand via de ingebouwde leesopdracht.

Standaard scant de read-instructie een regel met gegevens en splitst deze in velden. Gewoonlijk splitsen velden op met spaties en tabs, waarbij nieuwe regels op elke regel eindigen, maar u kunt dit gedrag wijzigen door de waarde voor het interne veldscheidingsteken (IFS) en het scheidingsteken voor het einde van de regel (-d) in te stellen.

< p>Als u een HTML-bestand wilt ontleden met read , stelt u de IFS in op een groter-dan-symbool (>) en het scheidingsteken op een kleiner-dan-symbool (<). Elke keer dat Bash een regel scant, wordt deze geparseerd naar de volgende < (het begin van een HTML-tag) splitst die gegevens vervolgens bij elke > (het einde van een HTML-tag). Deze voorbeeldcode vereist een invoerregel en splitst de gegevens in de variabelen TAG en VALUE:

local IFS='>' lees -d '<' TAGWAARDE

Laten we eens kijken hoe dit werkt. Beschouw dit eenvoudige HTML-bestand:

<img src=”logo.png” alt=”Mijn logo” /> <p>wat tekst</p> Advertentie

De eerste keer dat dit bestand wordt geparseerd, stopt het bij de eerste < symbool. Sinds < is het eerste teken van deze voorbeeldinvoer, wat betekent dat Bash een lege tekenreeks vindt. De resulterende TAG- en VALUE-tekenreeksen zijn ook leeg. Maar dat is prima voor mijn gebruik.

De volgende keer dat Bash de invoer leest, krijgt het img src=”logo.png”↲alt=”Mijn logo” />↲ met een nieuwe regel vlak voor de alt en stopt voor de < symbool op de volgende regel. Dan splitst read de regel op de > symbool, dat TAG achterlaat met img src=”logo.png”↲alt=”Mijn logo”/en VALUE met een lege nieuwe regel.

De derde keer dat het wordt gelezen, wordt het HTML-bestand geparseerd en krijgt het wat tekst. Bash splitst de string op de > resulterend in TAG met p en VALUE met wat tekst .

Een eenvoudige parser

Nu je begrijpt hoe je read moet gebruiken, is het gemakkelijk om een ​​langer HTML-bestand te ontleden met Bash. Begin met een Bash-functie genaamd xmlgetnext om de gegevens te ontleden met read , aangezien je dit keer op keer in het script zult doen. Ik noemde mijn functie xmlgetnext om me eraan te herinneren dat dit een vervanging is voor het Linux xmllint-programma, maar ik had het net zo gemakkelijk htmlgetnext kunnen noemen.

xmlgetnext () { local IFS='>' lees -d '<' TAG WAARDE }

Noem nu die xmlgetnext-functie om het HTML-bestand te ontleden. Dit is mijn volledige htmltags-script:

#!/bin/sh # print een lijst met alle html-tags xmlgetnext () { local IFS='>' lees -d '<' TAGWAARDE } kat $1 | terwijl xmlgetnext ; doe echo $TAG; klaar

De laatste regel is de sleutel. Het doorloopt het bestand met xmlgetnext om de HTML te ontleden en drukt alleen de TAG-vermeldingen af. En vanwege de manier waarop echo werkt met de standaard veldscheidingstekens, worden alle regels zoals img src=”logo.png”↲alt=”Mijn logo”/die een nieuwe regel bevatten op een enkele regel afgedrukt, als img src=”logo.png ” alt=”Mijn logo” /.

HTML ontleden in Bash

Advertentie

Om alleen de lijst met afbeeldingen op te halen, voer ik de uitvoer van dit script door grep om alleen de regels af te drukken met een img-tag op de begin van de regel.