nostream
Goto Top

Per Batch bestimmten Text aus mehreren .html Dateien gleichzeitig auslesen

Hallo und schönen Sonntag,

ich habe hier folgendes Problem:

Ich habe einen Ordner mit über 1000 .html Dateien mit verschiedenen Dateinamen bei denen ich in jeder Datei nach einem bestimmten Tag suchen muss:

<META NAME="description" CONTENT=" hier steht beliebiger Text ">  

anschließend müsste ich nur den Teil " hier steht belieber Text " ausgeben und nach einer weiteren HTML-Codestelle im selben .html Dokument suchen:

class="artikelpreis" id="preis" style="font-weight:bold;">30,00 &euro;</span><br>  

Hier interessiert nur " 30,00 " also der Betrag in EUR.

In der Ausgabe soll also stehen " hier steht beliebiger Text " dann ein " ; " damit ich die Werte einfach in Excel in 2 Spalten importieren kann, und dann noch " 30,00 ".

Ich hab` jetzt schon mal versucht ein Script, dass hier im Forum funktioniert hat folgendermaßen anzupassen:

@echo off & setlocal
set "Verzeichnis=C:\Dokumente und Einstellungen\nostream\Eigene Dateien\MeineSite\MeinOrdner"  
set "Typ=html"  
set "Liste=C:\Dokumente und Einstellungen\nostream\Eigene Dateien\MeineSite\Liste.txt"  

if exist "%Liste%" del "%Liste%"  
for %%i in ("%Verzeichnis%\*.%Typ%") do type "%%i"|findstr /i /c:"\* <META NAME="description" CONTENT= * >\*">nul && >>"%Liste%" echo %%i  

Hiermit wollte ich das Tag mit der meta description auslesen, aber das Script bricht mit folgender Meldung ab:

Script:

...\Batch.vbs
Zeile: 1
Zeichen: 1
Fehler: Ungültiges Zeichen
Code: 800A0408
Quelle: Kompilierungsfehler in Microsoft VBScript

Ich wäre euch sehr, sehr dankbar, wenn Ihr das Skript zum laufen bringen würdet, da ansonten alle Infos von Hand aus den über 1000 .html Dateien herauskopiert werden müssen.

Vielen Dank schonmal,
nostream

Content-Key: 119244

Url: https://administrator.de/contentid/119244

Printed on: April 25, 2024 at 09:04 o'clock

Mitglied: 76109
76109 Jun 28, 2009 at 12:27:47 (UTC)
Goto Top
Hallo nostream!

Wenn Du Batch-Code schreibst, dann musst Du der Datei den Namen *.bat oder *.cmd geben.

Gruß Dieter
Member: nostream
nostream Jun 28, 2009 at 12:49:36 (UTC)
Goto Top
Hallo Dieter,

oh, wie dumm von mir. Typischer Anfänger-Fehler.

Mit der Endung .bat läuft das Skript jetzt schonmal. Wie ich aber im cmd Fenster feststelle, sucht er nach dem meta tag description im Dateinamen und nicht im Inhalt der .html Datei. Folgendes wird in Endlosschleife ausgegeben:

- Ein Prozess hat versucht zu einer nicht bestehenden Pipe zu schreiben
- Datei "* <META NAME="description nicht gefunden

Was müsste ich denn hier anpassen? Wie man sieht hab` ich von der ganzen Materie wohl nur sehr wenig Ahnung.

Gruß,
nostream
Member: bastla
bastla Jun 28, 2009 at 13:03:42 (UTC)
Goto Top
Hallo nostream!

Einen einheitlichen Aufbau der fraglichen Zeilen wie in Deinem Beispiel und nur je eine "passende" Zeile vorausgesetzt, könnte es mit folgendem Batch gehen:
@echo off & setlocal enabledelayedexpansion
set "Verzeichnis=C:\Dokumente und Einstellungen\nostream\Eigene Dateien\MeineSite\MeinOrdner"  
set "Typ=html"  
set "Liste=C:\Dokumente und Einstellungen\nostream\Eigene Dateien\MeineSite\Liste.txt"  

if exist "%Liste%" del "%Liste%"  
for %%i in ("%Verzeichnis%\*.%Typ%") do (  
    for /f "tokens=3 delims=<=>" %%a in ('findstr /i /c:"META NAME=\"description\" CONTENT=" "%%i"') do set "Zeile=%%a"  
    for /f "tokens=5 delims=<=>&" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do echo !Zeile!;%%a  
)>>"%Liste%"  
Grüße
bastla
Member: nostream
nostream Jun 28, 2009 at 13:28:21 (UTC)
Goto Top
Hallo bastla,

vielen Dank für den Code. Sehr, sehr, sehr nett von Dir !!!

Ich werd`s dann heute Abend mal mit diesem Code probieren und nochmal berichten, ob`s denn funktioniert.

Muß jetzt leider erst mal weg - gehen zum Sonntagsessen ;)

Bis dann und Danke,

nostream
Member: nostream
nostream Jun 28, 2009 at 19:16:52 (UTC)
Goto Top
Hallo,

bin wieder zurück und hab`s kaum erwarten können den Batch durchlaufen zu lassen.

Es funktioniert auch und läuft derzeit noch, nur bei der Ausgabe müsste wahrscheinlich noch irgendetwas angepasst werden. Bisher enthält die Datei Liste.txt folgenden Inhalt:

"description" CONTENT;nur 7,50   
"description" CONTENT;nur 8,00   
"description" CONTENT;nur 8,00   
"description" CONTENT;nur 7,50   

Wäre echt dankbar, wenn wir das noch ganz hinbekommen würden, wo die Preise ja schonmal stimmen face-smile))

Vielen Dank,
nostream
Member: bastla
bastla Jun 28, 2009 at 19:23:26 (UTC)
Goto Top
Hallo nostream!

Ändere versuchsweise in Zeile 8 den Wert für "tokens" auf 4 (anstelle von 3).

Grüße
bastla
Member: nostream
nostream Jun 28, 2009 at 20:35:35 (UTC)
Goto Top
Hey,

super jetzt funktionierts !!!!! DANKE

Wieso musste denn der Wert hier von "3" auf "4" geändert werden? Naja, bestimmt sollte ich hier erstmal `nen Basiskurs machen!

Was mich als Variante interessieren würde ist, wie ich z. B. noch einen 3ten, 4ten, usw. Wert wie den folgenden Tag abfragen könnte:

<title> " hier steht der Titel "</title>  

Wobei wieder nur der Wert zwischen den Title-Tags mit einem " ; " abgetrennt für Excel ausgegeben werden soll. Gut wäre es, wenn der Title Tag an erster Stelle der Ausgabe stünde.

Außerdem wäre die Weiterbearbeitung in Excel noch wesentlich einfacher, wenn man die Infos aus folgendem sich wiederholendem HTML-Code mit einbinden würde, da die Meta-Description alle Informationen auf einmal enthält:

<p class="navi">Sie sind hier: <a href="index.html">Startseite</a> &raquo; <a href="Hersteller.html">Hersteller</a> &raquo; <a href="Serie.html">Serie</a> &raquo; <a href="XYZ1000-Serie.html">XYZ1000-Serie</a> &raquo; <a href="Modell.html">Modell</a><br /></p>  

Interessant wären hier die Informationen "Hersteller", "Serie", "XYZ1000-Serie" und "Modell" und natürlich wieder ein " ; " zwischen den einzelnen Werten für die Excel Spalten.


<span class="artikelnummer">ArtikelNr.: XXXX123456</span>  

Hier interessiert noch die ArtikelNr.: .

<span class="artikelpreis"><b>Unser Preis: </b></span><span class="artikelpreis" id="preis" style="font-weight:bold;">85,00 &euro;</span>  

Und hier letztlich auch wieder die 85,00 wobei es hier innerhalb der verschiedenen .html Dateien eine Varianz zu obiger Angabe im ersten Post des Themas

"class="artikelpreis" id="preis" style="font-weight:bold;">30,00 &euro;</span><br>"   

zu geben scheint, da in der Liste.txt in manchen Zeilen statt dem EUR Wert nur "Unser Preis:" steht.

Das mit dem Preis unterscheiden zu können wäre zwar gut, ist aber nicht zwingend erforderlich.

Wichtig wäre für Excel, wenn machbar, folgender Aufbau:

1. Spalte: Art.Nr.:
2. Spalte: Hersteller
3. Spalte: Serie
4. Spalte: XYZ-Serie
5. Spalte: Modell
6. Spalte: die Meta-Description, was ja bereits Zeile 8 des obigen Skripts entsrpicht
7. Spalte: der Inhalt zwischen dem Title-Tag
8. Spalte: Der Preis wie in Zeile 9 des Skripts
9. Spalte: Der Preis wie weiter unten beschreiben

Falls eine der beiden Spalten mit dem Preis einfach leer bliebe, wäre dies kein Problem.

Puh, das ist `ne Menge Holz, was der Junge da noch will ;)

Um mich gleich mal daran zu versuchen es selbst zu probieren hier, was ich für die Art.Nr.: zwischen Zeile 7 und Zeile 8 einfügen würde:

for /f "tokens=3 delims=<=>" %%a in ('findstr /i /c:"span class=\"artikelnummer\" ArtikelNr.:" "%%i"') do set "Zeile=%%a"  

Hierzu 2 Fragen:

1. Wozu der Backslash \ nach dem "span class=" ?
2. Reicht es das " ; " in der 9ten Zeile einmal auszugeben?

Sorry, dass die Antwort jetzt `ne Stunde gedauert hat, aber mir ist noch so viel eingefallen.

Vielen Dank,
nostream
Member: bastla
bastla Jun 28, 2009 at 21:09:21 (UTC)
Goto Top
Hallo nostream!
Wieso musste denn der Wert hier von "3" auf "4" geändert werden?
Mit der "token"-Nr wird festgelegt, welcher Teil einer Zeile verwendet werden soll, wobei die einzelnen Teile durch die als "delims" angegebenen Zeichen getrennt sind. Lt Deinem Beispiel
<META NAME="description" CONTENT=" hier steht beliebiger Text ">
wären bei Verwendung der Trennzeichen "<", "=" und ">" folgende "tokens" entstanden (die Trennzeichen selbst werden natürlich weggelassen):
META NAME
"description" CONTENT  
" hier steht beliebiger Text "  
Da die Zeilen in Deinen "Echt"-Dateien offensichtlich noch einen zusätzlichen Bestandteil enthalten, habe ich eben geraten, dass der gesuchte Text als Teil 4 zu finden ist ...
1. Wozu der Backslash \ nach dem "span class=" ?
Eigentlich steht der Backslash vor dem folgenden Anführungszeichen, da dieses für die Verwendung mit "findstr" als "gewöhnliches, zu suchendes Zeichen" gekennzeichnet werden muss (dies gilt auch zB für den "\" selbst, der dann "\\" zu schreiben ist, oder für ".", "$" oder "^").
2. Reicht es das " ; " in der 9ten Zeile einmal auszugeben?
Nein; wenn Du mehrere Felder in Deinem auszugebenden Datensatz hast, ist auch die entsprechende Anzahl an ";" erforderlich. In der angesprochenen Zeile 9 habe ich nur eine Abkürzung genommen; besser verständlich wäre folgende auf 2 Zeilen verteilte Schreibweise:
for /f "tokens=5 delims=<=>&" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do set "Zeile=!Zeile!;%%a"
echo !Zeile!
In der Variablen %Zeile% (bei Verwendung von "delayedExpansion" als !Zeile! zu schreiben) wird die Ausgabezeile zusammengesetzt und kann dann am Ende der Schleife ausgegeben werden - damit sollte auch klar sein, wie weitere Felder eingebaut werden können. Die Zerlegung kann wieder nach dem gleichen Muster wie oben erfolgen - am Beispiel der Zeile
<title> " hier steht der Titel "</title>
sähe das so aus:
for /f "tokens=2 delims=<>" %%a in ('findstr /i /c:"<title>" "%%i"') do set "Zeile=!Zeile!;%%a"
Für die "navi"-Zeile mit mehreren verwertbaren Teilen kannst Du auch mehrere "tokens" angeben, etwa
for /f "tokens=8,12,16,20 delims=<>" %%a in ('findstr /i /c:"<p class=\"navi\"" "%%i"') do set "Zeile=!Zeile!;%%a;%%b;%%c;%%d"  
Auf dieser Basis könntest Du versuchen, die gewünschte Ausgabezeile zusammenzusetzen.

Grüße
bastla
Member: nostream
nostream Jun 28, 2009 at 21:20:17 (UTC)
Goto Top
Hallo bastla,

O. K. das hilft mir schonmal auf die Sprünge face-smile

Danke für die viele Mühe, die DU Dir machst. Zu nett.

Ich versuch`s dann mal und melde mich so in 1, 2 Tagen oder bei vorherigen Wiedrigkeiten nochmal und berichte wie weit ich bin bzw. ob`s schon geklappt hat.

Jetzt aber erstmal schlafen. Morgen ist wieder Arbeit.

Viele Grüße,
nostream
Member: nostream
nostream Jun 29, 2009 at 22:24:55 (UTC)
Goto Top
Hallo bastla,

das mit der Zusammensetzung der "navi"-Zeile bedarf noch reichlich Probierarbeit, deswegen würde ich mich Momentan ersmal auf folgende Zeilen beschränken:

@echo off & setlocal enabledelayedexpansion
set "Verzeichnis=C:\Dokumente und Einstellungen\nostream\Eigene Dateien\MeineSite\MeinOrdner"  
set "Typ=html"  
set "Liste=C:\Dokumente und Einstellungen\nostream\Eigene Dateien\MeineSite\Liste.txt"  

for %%i in ("%Verzeichnis%\*.%Typ%") do (  
for /f "tokens=4 delims=<=>" %%a in ('findstr /i /c:"META NAME=\"description\" CONTENT=" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=8 delims=<=/>" %%a in ('findstr /i /c:"span class=\"artikelnummer\"" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=3 delims=<>" %%a in ('findstr /i /c:"<title>" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=5 delims=<=>&" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do set "Zeile=!Zeile!;%%a"  
echo !Zeile!
)>>"%Liste%"  

Leider klappt die Ausgabe nicht so ganz. Siehst Du den Fehler irgendwo?

Vielen Dank,
nostream
Member: bastla
bastla Jun 30, 2009 at 06:10:20 (UTC)
Goto Top
Hallo nostream!
Leider klappt die Ausgabe nicht so ganz.
... ließe sich doch sicher noch etwas konkretisieren (etwa mit Beispielen für Ausgangsdaten / Ergebnis), da, wie es aussieht, Deine oben geposteten Musterzeilen nicht ganz dem tatsächlichen Aufbau entsprechen ...
Auf jeden Fall muss es beim ersten Feld nur heißen:
<code type="plain>... do set Zeile=%%a
damit für jede Datei eine neue Zeile erstellt wird.

Für die Artikelnummer würde auf Basis der oben von Dir geposteten Zeile
<span class="artikelnummer">ArtikelNr.: XXXX123456</span>
zB
for /f "tokens=3 delims=<:>" %%a in ('findstr /i /c:"span class=\"artikelnummer\"" "%%i"') do set "Zeile=!Zeile!;%%a"
funktionieren (mit ":" anstatt "=" als Trennzeichen - die Aufteilung "span class" und "artikelnummer" bringt ja nix).

Grüße
bastla
Member: nostream
nostream Jun 30, 2009 at 20:24:10 (UTC)
Goto Top
Zitat von @bastla:
Auf jeden Fall muss es beim ersten Feld nur heißen:
<code type="plain>... do set Zeile=%%a
damit für jede Datei eine neue Zeile erstellt wird.

Ja, genau das war, was bei der Ausgabe nicht geklaptt hatte, da die einzelnen Zeilen mehrfach und dann auch noch die Bestandteile mehrfach in der Zeile ausgegeben wurden.

Für die Artikelnummer würde auf Basis der oben von Dir
geposteten Zeile
<span class="artikelnummer">ArtikelNr.: XXXX123456</span> 
zB
for /f "tokens=3 delims=<:>" %%a in ('findstr /i /c:"span class=\"artikelnummer\"" "%%i"') do set "Zeile=!Zeile!;%%a"
funktionieren (mit ":" anstatt "=" als Trennzeichen - die Aufteilung "span class" und "artikelnummer" bringt ja nix).

Das hat mit probieren geklappt, da ich mir noch nicht so ganz sicher bin, was jetzt alles als "tokens" gezählt wird. Weder das zählen der Schritte noch der einzelnen "delims" führte bei den Abfragen zum gewünschten Ergebnis. Ich gehe momentan davon aus, dass wenn z. B. in der Zeile ein <br> steht, dieses als ein token zählen müsste. Schwieriger ist`s, wenn z. B. wie bei der span class erst ein "<" steht, dann weitere delims, die z. B. nur ein Zeichen zusätzlich enthalten wie "</span> und was dann je genau alles ein token darstellt? Aber klappen tut`s dann irgendwann mit +- Schritten von 1 face-smile


Grüße
bastla


Ob das "echo" jetzt passt probier ich gleich mal aus.

Danke,
nostream
Member: bastla
bastla Jun 30, 2009 at 21:32:15 (UTC)
Goto Top
Hallo nostream!
... da ich mir noch nicht so ganz sicher bin, was jetzt alles als "tokens" gezählt wird. Weder das zählen der Schritte noch der einzelnen "delims" führte bei den Abfragen zum gewünschten Ergebnis. Ich gehe momentan davon aus, dass wenn z. B. in der Zeile ein <br> steht, dieses als ein token zählen müsste. Schwieriger ist`s, wenn z. B. wie bei der span class erst ein "<" steht, dann weitere delims, die z. B. nur ein Zeichen zusätzlich enthalten wie "</span> und was dann je genau alles ein token darstellt?
Mehrere aufeinander folgende "Delimiter"-Zeichen werden nur als ein einziges Trennzeichen interpretiert, daher wäre in Deinem Beispiel mit "delims=<>/" (Reihenfolge egal) das "span" ein "Token", während sich zwischen "<" und "/" nichts befindet, also auch kein "Token" (was manchmal nachteilig ist, da es ja zB in CSV-Dateien tatsächlich leere Felder zwischen 2 Trennzeichen geben kann)

Grüße
bastla
Member: nostream
nostream Jun 30, 2009 at 21:59:44 (UTC)
Goto Top
Hallo bastla,

O. K.

Soweit scheit dann das meiste klar zu sein. Im ersten Feld nur

do set Zeile=%%a

in allen weiteren Feldern dann

do set "Zeile=!Zeile!;%%a" (um die 2te Ausgabe hinter die erste anzufügen)  

und letztlich form verlassen der For-Schleife ein

echo !Zeile! 

bzw. ein

do echo !Zeile!;%%a

gleich am Ende der letzten Feldabfrage.

Und bei den Delimetern zählen immer 2 aufeinanderfolgende Zeichen als ein Token, sofern noch Text dazwischen steht und nicht nur die Delimeter direkt nacheinander folgen, ganz davon abgesehen, ob das in der HTML-Syntax Sinn macht ;)

Die Ausgabe wird zwar gerade noch erstellt und manches ist einfach etwas hakelig, aber für die jetzigen Zwecke und zur optimierung in Excel kann ich damit erstmal arbeiten, zumal es beim HTML-Code auch kleinere Abweichungen zu geben scheint, die man anstatt abzufangen auch in Excel löschen kann, wobei das Abfangen natürlich die interessantere Methode wäre.

Vielen Dank erstmal Dir Bastla. Besser geht`s einfach nicht :=) :=) :=)

nostream
Member: nostream
nostream Jul 01, 2009 at 00:31:25 (UTC)
Goto Top
Hi Bastla,

STOP! Leider zu früh gefreut, es besteht noch folgendes Problem:

if exist "%Liste%" del "%Liste%"  
for %%i in ("%Verzeichnis%\*.%Typ%") do (  
for /f "tokens=8 delims=<=/>" %%a in ('findstr /i /c:"span class=\"artikelnummer\"" "%%i"') do set Zeile=%%a  
for /f "tokens=3 delims=<>" %%a in ('findstr /i /c:"<title>" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=14 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelnamelink\"" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=5 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=12 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do echo !Zeile!;%%a  
)>>"%Liste%"  

Beim Artikelpreis in den letzten beiden Zeilen mit " for /f " besteht eine Varianz: Einaml kommt der Preis rund bei der Hälfte der Artikel bei token 5 vor, beim Rest an Stelle 12. Zusätzlich steht bei " tokens=12 " auch 2x die "<class="artikelpreis" in der selben Zeile. Obiges Batch gibt jedoch überhaupt keine Werte aus, wenn im letzten Feld nichts gefunden wird. Schreibe ich in der letzten Zeile aber auch "do set"

for /f "tokens=12 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do set "Zeile=!Zeile!;%%a"  

und geb das echo mit

echo !Liste!

aus, sind die Werte unschön sortiert und schlechter strukturiert.

z. B. so:

>++++
>+++++
>++++++
>+++++++
>++
>++
>++
>++
>+++++
>++++++
>+++++++

Dabei sollte eine Zeile eigentlich 2 " + " Symbole haben, es werden aber manche Werte für 4 oder 5 Zeilen doppelt ausgegeben, wobei der überflüssige Teil immer nochmal zusätzlich angehängt wird.

Könnte man hier ein "IF-Else" einbauen um " do echo !Zeile!;%%a " zweimal verwenden zu können? Also:

if exist "%Liste%" del "%Liste%"  
for %%i in ("%Verzeichnis%\*.%Typ%") do (  
for /f "tokens=8 delims=<=/>" %%a in ('findstr /i /c:"span class=\"artikelnummer\"" "%%i"') do set Zeile=%%a  
for /f "tokens=3 delims=<>" %%a in ('findstr /i /c:"<title>" "%%i"') do set "Zeile=!Zeile!;%%a"  
for /f "tokens=14 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelnamelink\"" "%%i"') do set "Zeile=!Zeile!;%%a"  

**IF** 

for /f "tokens=5 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do echo !Zeile!;%%a  

**ELSE**

for /f "tokens=12 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do echo !Zeile!;%%a  
)>>"%Liste%"  
Gruß,
nostream
Member: bastla
bastla Jul 01, 2009 at 06:15:01 (UTC)
Goto Top
Hallo nostream!

Schematisch könnte die gewünschte Vorgangsweise etwa so umgesetzt werden:
...
set "Preis="  
for /f "tokens=12 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do set "Preis=%%a"  
if not defined Preis for /f "tokens=5 delims=<=>" %%a in ('findstr /i /c:"class=\"artikelpreis\"" "%%i"') do set "Preis=%%a"  
echo !Zeile!;!Preis!
)>>"%Liste%"  
Mit der Zeile 2 wird der alte Inhalt (von der vorigen Datei) der Variablen Preis und damit die Variable selbst gelöscht, sodass diese in Zeile 4 mit "if defined" geprüft werden kann. "Defined" ist sie nur, wenn sie vorher in Zeile 3 einen Wert (aus Token 12) erhalten hat. Token 12 zuerst zu prüfen ist nötig, da es Token 5 immer gibt, wenn ein Token 12 vorhanden ist.

Grüße
bastla