Analysera HTML i Bash

0
44

Jag har en process där jag måste kopiera alla bilder från en webbsida sida. Jag brukade köra denna process med xmllint, som kommer att bearbeta en XML- eller HTML -fil och skriva ut de poster du anger. Men när min servervärdleverantör uppgraderade sina system, inkluderade de inte xmllint. Så jag var tvungen att hitta ett annat sätt att extrahera en lista med bilder från en HTML -sida. Det visar sig att du kan göra det här i Bash.

Det lästa uttalandet

Du kanske inte tror att Bash kan analysera datafiler, men det kan med lite smart tänkande. Bash, som andra UNIX-skal före den, kan analysera rader en i taget från en fil via det inbyggda läsuttrycket.

Som standard skannar read -satsen en rad data och delar den i fält. Vanligtvis läser uppdelningsfält med mellanslag och flikar, med nya rader som slutar varje rad, men du kan ändra detta beteende genom att ställa in Internal Field Separator (IFS) -värdet och end-of-line-avgränsaren (-d).

< p>Om du vill analysera en HTML-fil med läsning ställer du in IFS på en symbol som är större än (& gt;) och avgränsaren till en symbol som är mindre än (& lt;). Varje gång Bash skannar en rad, analyseras den till nästa & lt; (starten på en HTML -tagg) delar sedan upp dessa data vid varje & gt; (slutet på en HTML -tagg). Denna exempelkod tar en rad med inmatning och delar upp data i TAG- och VALUE -variablerna:

lokal IFS = '& gt;' läs -d '& lt;' TAG VALUE

Låt oss utforska hur detta fungerar. Tänk på den här enkla HTML -filen:

& lt; img src = “logo.png” alt = “Min logotyp” /& gt; & lt; p & gt; lite text & lt;/p & gt; Annons

Första gången man läser analyserar den här filen, den stannar vid första & lt; symbol. Eftersom & lt; är det första tecknet i denna provinmatning, det betyder att Bash hittar en tom sträng. De resulterande TAG- och VALUE -strängarna är också tomma. Men det är bra för mitt användningsfall.

Nästa gång Bash läser inmatningen får den img src = “logo.png” ↲alt = “Min logotyp” /& gt; ↲ med en newline precis före alt och stannar före & lt; symbolen på nästa rad. Läs sedan delar raden på & gt; symbol, som lämnar TAG med img src = “logo.png” ↲alt = “Min logotyp”/och VALUE med en tom ny rad.

Tredje gången som läses analyserar HTML -filen, den får p & gt; lite text. Bash delar strängen vid & gt; vilket resulterar i att TAG innehåller p och VALUE med lite text.

En enkel parser

Nu när du förstår hur du använder läs är det lätt att analysera en längre HTML -fil med Bash. Börja med en Bash -funktion som heter xmlgetnext för att analysera data med läsning, eftersom du kommer att göra detta om och om igen i skriptet. Jag namngav min funktion xmlgetnext för att påminna mig om att detta är en ersättning för Linux xmllint -programmet, men jag kunde lika gärna ha döpt det till htmlgetnext.

xmlgetnext () {local IFS = '& gt;' läs -d '& lt;' TAG VALUE}

Ring nu den xmlgetnext -funktionen för att analysera HTML -filen. Detta är mitt fullständiga htmltags -skript:

#!/Bin/sh # skriv ut en lista över alla html -taggar xmlgetnext () {lokal IFS = '& gt;' läs -d '& lt;' TAG VALUE} kat $ 1 | medan xmlgetnext; echo $ TAG; gjort

Den sista raden är nyckeln. Den går igenom filen med hjälp av xmlgetnext för att analysera HTML -filen och skriver ut endast TAG -poster. Och på grund av hur eko fungerar med standardfältavskiljare, skrivs alla rader som img src = “logo.png” ↲alt = “Min logotyp”/som innehåller en ny rad ut på en enda rad, som img src = “logo.png “alt =” Min logotyp “/.

Parsing HTML in Bash

Advertisement

För att hämta bara en lista med bilder kör jag utmatningen av detta skript genom grep för att bara skriva ut raderna som har en img -tagg på början av raden.