HTML in Bash parsen

0
305

Ich habe einen Prozess, bei dem ich alle Bilder aus einem Web kopieren muss Seite. Früher habe ich diesen Prozess mit xmllint ausgeführt, das eine XML- oder HTML-Datei verarbeitet und die von Ihnen angegebenen Einträge ausdruckt. Aber als mein Server-Host-Provider seine Systeme aktualisierte, enthielten sie xmllint nicht. Also musste ich einen anderen Weg finden, um eine Liste von Bildern aus einer HTML-Seite zu extrahieren. Es stellt sich heraus, dass Sie dies in Bash tun können.

Die read-Anweisung

Sie denken vielleicht nicht, dass Bash Datendateien analysieren kann, aber mit etwas klugem Denken ist es möglich. Bash kann, wie andere UNIX-Shells zuvor, Zeilen einzeln aus einer Datei über die eingebaute read-Anweisung parsen.

Standardmäßig scannt die read-Anweisung eine Datenzeile und teilt sie in Felder auf. Normalerweise teilt Read Felder mit Leerzeichen und Tabulatoren auf, wobei jede Zeile mit Zeilenumbrüchen endet. Sie können dieses Verhalten jedoch ändern, indem Sie den Wert für das interne Feldtrennzeichen (IFS) und das Zeilenendetrennzeichen (-d) festlegen.

< p>Um eine HTML-Datei mit read zu analysieren, setzen Sie den IFS auf ein Größer-als-Symbol (>) und das Trennzeichen auf ein Kleiner-als-Symbol (<). Jedes Mal, wenn Bash eine Zeile scannt, parst sie bis zur nächsten < (der Anfang eines HTML-Tags) teilt diese Daten dann bei jedem > (das Ende eines HTML-Tags). Dieser Beispielcode nimmt eine Eingabezeile und teilt die Daten in die Variablen TAG und VALUE auf:

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

Sehen wir uns an, wie das funktioniert. Betrachten Sie diese einfache HTML-Datei:

<img src=”logo.png” alt=”Mein Logo” /> <p>etwas Text</p> Werbung

Wenn read diese Datei zum ersten Mal parst, stoppt es beim ersten < Symbol. Da < ist das erste Zeichen dieser Beispieleingabe, d. h. Bash findet einen leeren String. Die resultierenden TAG- und VALUE-Strings sind ebenfalls leer. Aber das ist für meinen Anwendungsfall in Ordnung.

Wenn Bash das nächste Mal die Eingabe liest, erhält sie img src=”logo.png”↲alt=”My logo” />↲ mit a Zeilenumbruch direkt vor dem Alt und endet vor dem < Symbol in der nächsten Zeile. Dann teilt read die Zeile am > -Symbol, das TAG mit img src=”logo.png”↲alt=”My logo”/und VALUE mit einem leeren Zeilenumbruch hinterlässt.

Wenn read die HTML-Datei zum dritten Mal parst, erhält sie einen Text. Bash teilt die Saite am > was zu einem TAG mit p und VALUE mit etwas Text führt.

Ein einfacher Parser

Nachdem Sie nun die Verwendung von read verstanden haben, ist es einfach, eine längere HTML-Datei mit Bash zu parsen. Beginnen Sie mit einer Bash-Funktion namens xmlgetnext, um die Daten mit read zu analysieren, da Sie dies im Skript immer wieder tun werden. Ich habe meine Funktion xmlgetnext genannt, um mich daran zu erinnern, dass dies ein Ersatz für das Linux-Programm xmllint ist, aber ich hätte sie genauso gut htmlgetnext nennen können.

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

Rufen Sie nun diese xmlgetnext-Funktion auf, um die HTML-Datei zu analysieren. Dies ist mein komplettes HTML-Tags-Skript:

#!/bin/sh # eine Liste aller HTML-Tags ausgeben xmlgetnext () { local IFS='>' lesen -d '<' TAG-WERT } Katze $1 | while xmlgetnext ; echo $TAG ; done

Die letzte Zeile ist der Schlüssel. Es durchläuft die Datei mit xmlgetnext, um den HTML-Code zu analysieren, und gibt nur die TAG-Einträge aus. Und da echo mit den Standard-Feldtrennern arbeitet, werden alle Zeilen wie img src=”logo.png”↲alt=”My logo”/die einen Zeilenumbruch enthalten auf einer einzigen Zeile gedruckt, als img src=”logo.png ” alt=”Mein Logo” /.

HTML in Bash parsen

Werbung

Um nur die Liste der Bilder abzurufen, lasse ich die Ausgabe dieses Skripts über grep laufen, um nur die Zeilen zu drucken, die ein img-Tag am Anfang der Zeile.