staging.inyokaproject.org

grep in html Dokumenten

Status: Gelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

Herbststurm

Anmeldungsdatum:
27. Mai 2011

Beiträge: 244

Hallo

Ich ziehe über wget den Code einer Homepage und speichere diesen in eine Textdatei:

1
wget -nv -qO- http://www.finanzen.net/aktien/DAX-Realtimekurse >> ./DAX_html

Wenn ich nun etwas aus dem file mit grep suchen möchte erhalte ich Kilometerlange ausgaben. Woran liegt dies?

1
grep -a -w "DAX Tick Historie" DAX_html

Grüße

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Das ist ein wunderschönes Beispiel dafür, warum grep denkbar ungeeignet ist für das Abgrasen von HTML-Dokumenten.

1.) Herbststurm schrieb:

1
wget -nv -qO- http://www.finanzen.net/aktien/DAX-Realtimekurse >> ./DAX_html

Damit hängst Du jeden neuen Download an die vorhandene Datei hinten an. Ist das Absicht ?

2.) Herbststurm schrieb:

Wenn ich nun etwas aus dem file mit grep suchen möchte erhalte ich Kilometerlange ausgaben. Woran liegt dies?

Ganz einfach daran, dass die betreffenden HTML- Zeilen tatsächlich so lang sind ! → Guck Dir die Datei doch mal an, z.B. mit geany DAX_html.

Mal eine Gegenfrage: Was möchtest Du denn aus dieser Seite herausbekommen ?

track

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Werkzeuge wie xmlstarlet sind im Allgemeinen besser geeignet solche Extraktionen zu machen. In einigen Fällen hilft auch die Option "-o" der grep-Werkzeuge:

1
fgrep -a -o -w 'DAX Tick Historie' DAX_html

In diesem Fall braucht man kein grep, weil Dein Suchmuster sowieso keine Metazeichen enthält.

Ich nehme für so etwas am liebsten Ruby mit Nokogiri, weil letzteres sowohl XML als auch HTML verarbeiten und mit CSS-Selektoren und XPath suchen kann.

Herbststurm

(Themenstarter)

Anmeldungsdatum:
27. Mai 2011

Beiträge: 244

Ziel soll es sein von der Homepage in der Box "DAX DB Realtime Indikation*" einmal den Punktestand sowie die zugehörige Kurszeit zu extraieren.

Ruby ist doch eine Programmiersprache? Nur für diesen Zweck Ruby zu lernen ist mir zu krass. xmlstarlet zu verwenden wäre eine Idee aber das sieht auch kompliziert aus. Hast du da ein Beispiel für die Extraktion?

Grüße

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Na ja, xmlstarlet kommt mit HTML nicht klar. - geht hier also nicht.
Und selbst tidy beschwert sich, dass diese Seite "proprietary HTML" sei. Die haben da also etwas "Giftkram" eingebaut.

Ich nehme mal an, es geht hier am Ende darum, die Kurse möglichst real-time zu ernten ...?
Und das macht diese Seite mit irgend einem Skript, das dann das HTML bedient.

Man sieht bei der Darstellung mit w3m deutlich, dass rein statisch immer nur 1 Zeile der aktuellen Kurse vorhanden ist.
- den Rest erledigt wie gesagt ein Skript.

Von daher wird es wahrscheinlich fruchtbarer sein, wenn man dieses Skript analysiert und guckt, woher das die Zahlen zieht. Dann kann man sich die ganze Seite sparen und die Zahlen selber dort abholen ... 😉

Aber wie gesagt: das ist ganz und gar kein Fall für grep (und wahrscheinlich auch nicht für XML), sondern eine Aufgabe für Skript-Analyse.

Dazu kann man die Datei als 1. Schritt mal ganz plump nach Tags umbrechen und anzeigen:

1
2
sed 's/></>\n</g' DAX_html  >  DAX_n.html
gedit  DAX_n.html

Dann sprengt einem die überlange Zeile schon mal nicht mehr den Editor. (und für HTML ist es egal: das beachtet sowieso nur die Tags !)

Mal so in der Richtung ...

track

coram

Anmeldungsdatum:
17. Januar 2015

Beiträge: Zähle...

Wenn es Dir um die Inhalte und nicht um den HTML-Code drumherum geht, könntest Du einen textbasierten Browser wie z. B. links2 zu Hilfe nehmen:

:~$ links2 -dump DAX_html | grep  "DAX Tick Historie"
DAX Tick Historie

Wobei es Dir, wie ich mal vermute, in diesem Fall auch um die folgenden Zeilen geht ☺ :

:~$ links2 -dump DAX_html | grep  -A 3 "DAX Tick Historie"
DAX Tick Historie

   Zeit                     Bid                      Ask                      
   11:08:30                 10.573,50                10.573,50

Oder greife doch ohne Speicherung einer Zwischendatei direkt auf die Webseite zu:

:~$ links2 -dump http://www.finanzen.net/aktien/DAX-Realtimekurse | grep  -A 3 "DAX Tick Historie"
DAX Tick Historie

   Zeit                     Bid                      Ask                      
   11:47:24                 10.592,00                10.592,00 

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Ah - inzwischen hattest Du noch geschieben.
Herbststurm schrieb:

Ziel soll es sein von der Homepage in der Box "DAX DB Realtime Indikation*" einmal den Punktestand sowie die zugehörige Kurszeit zu extraieren.

Vermutlich ist es einfacher, die Zahlen woanders abzuholen.

Wie gesagt, für realtime sollte man das zugehörige Skript analysieren, alles andere ist viel zu viel Overhead.
Wenn Du das nicht willst, und auch nur einzelne Snaphots brauchst, wäre es wohl die einfachste schmutzig-schnelle Lösung, die Seite mit w3m abzuholen und diese Ausgabe dann mit 'grep' abzuernten:

1
w3m -no-cookie  http://www.finanzen.net/aktien/DAX-Realtimekurse  |  grep -A1 'Zeit.*Bid.*Ask'

Sowas in der Richtung ...

LG,

track

p.s.:
oh, coram hat in der Zwischenzeit auch sowas vorgeschlagen ! - schön, dann hast Du ja schon mal 2 solche Lösungen zur Auswahl.

user_unknown

Avatar von user_unknown

Anmeldungsdatum:
10. August 2005

Beiträge: 17630

track schrieb:

Das ist ein wunderschönes Beispiel dafür, warum grep denkbar ungeeignet ist für das Abgrasen von HTML-Dokumenten.

Nein, das ist ein Beispiel dafür, dass man die Zeilenorientierung von Grep im Auge haben muss, wenn man sowas macht.

1
2
3
egrep -a -o "[0-9.,]{4,11}.{39}Punkte|Kurszeit.*quotetime.{2}[0-9:]{8}" dax.html 
10.594,50</div></th><th class="text_left"><span>Punkte
Kurszeit</strong></td><td class="border_right"><div source="lightstreamer" table="2" item="X0000010700DEDB2KE7=DBBL" field="quotetime">12:00:02

Noch etwas Schlusskosmetik und fertig ist das Häuschen.

Herbststurm

(Themenstarter)

Anmeldungsdatum:
27. Mai 2011

Beiträge: 244

Das hat mir sehr geholfen. Vielen Dank ☺

Doc_Symbiosis

Avatar von Doc_Symbiosis

Anmeldungsdatum:
11. Oktober 2006

Beiträge: 4453

Falls dein Problem damit gelöst ist, setze den Thread doch bitte noch auf gelöst.

Herbststurm

(Themenstarter)

Anmeldungsdatum:
27. Mai 2011

Beiträge: 244

Ich verwende nun diesen Code:

1
w3m -no-cookie  http://www.finanzen.net/aktien/DAX-Realtimekurse  |  grep -A1 'Zeit.*Bid.*Ask' | tail -n 1

Ich würde gerne an diese Ausgabe noch folgenden Befehl anknüpfen

1
date "+%d/%m/%y"

aber mittels && wird das Datum in eine neue Zeile geschrieben. Was muss man machen um die Ausgabe des Datums an die Kursdaten anzuknüpfen?

Grüße

coram

Anmeldungsdatum:
17. Januar 2015

Beiträge: 645

Vielleicht gibt es eine elegantere Möglichkeit, aber ich würde es so machen:

echo -n $(w3m -no-cookie http://www.finanzen.net/aktien/DAX-Realtimekurse | grep -A1 'Zeit.*Bid.*Ask' | tail -n 1) "- " && date "+%d/%m/%y"

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Dafür würde ich Dir vorschlagen, diese Ausgabe mit einer Command Substitution einzufangen und dann als Array-Eingabe zu verarbeiten. Das teilt automatisch alles hübsch in Komponenten auf:

track@track:~$ w3m -no-cookie http://www.finanzen.net/aktien/DAX-Realtimekurse  |  grep -A1 'Zeit.*Bid.*Ask'
  Zeit      Bid       Ask
18:52:48 10.592,00 10.592,00
track@track:~$ feld=( $(w3m -no-cookie http://www.finanzen.net/aktien/DAX-Realtimekurse | grep -A1 'Zeit.*Bid.*Ask') )
track@track:~$ for i in 0 1 2 3 4 5; do
> echo ${feld[i]}
> done
Zeit
Bid
Ask
18:53:23
10.592,00
10.592,00 

Und die Array-Variablen kannst Du dann auch direkt an date verfüttern:

track@track:~$ date -d ${feld[3]} "+%c  ${feld[1]}: ${feld[4]}  ${feld[2]}: ${feld[5]}"
Di 23 Aug 2016 18:53:23 CEST  Bid: 10.592,00  Ask: 10.592,00 

Das dürfte so ± die einfachste Lösung sein.

LG,

track

p.s.:
oh, da fällt mir gerade noch eine hübsche Alternative ein, wenn Du die Zerlegung usw. nicht mit der Shell machst, sondern mit awk :

track@track:~$ w3m -no-cookie http://www.finanzen.net/aktien/DAX-Realtimekurse \
 |  awk '/Zeit.*Bid.*Ask/ { getline; print strftime()," Bid:",$2," Ask:",$3 }'
Di Aug 23 19:23:10 CEST 2016  Bid: 10.594,50  Ask: 10.594,50 

Herbststurm

(Themenstarter)

Anmeldungsdatum:
27. Mai 2011

Beiträge: 244

Die Idee über das Array gefällt mir. Dem werde ich auch nachgehen. Ich habe es nochmal etwas umgeändert und bin zu diesem Zwischenstand gekommen:

1
2
3
4
5
6
7
8
#!/bin/bash

echo "#Zeit Geldkurs Datum" >> DAX_tick.txt

while :; do
(echo -n $(w3m -no-cookie http://www.finanzen.net/aktien/DAX-Realtimekurse | grep -A1 'Zeit.*Bid.*Ask' | tail -n 1 | sed -r 's/.{0}(.{18}).*/\1/') "" && date "+%d.%m.%y") >> DAX_tick.txt
sleep 12
done

Grüße

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Oben habe ich gerade noch eine schöne, schlanke Variante mit awk nachgetragen ...

Brauchst Du den Aktienkurs eigentlich wirklich im 12-Sekundentakt ??

Sonst würde ich den Abruf vielleicht eher mit cron steuern (im Minutentakt). Außerdem fallen da ja jede Menge redundanter Zahlen an, das bläht die Log-Datei enorm auf. Eigentlich würde es da ja reichen, wenn Du immer nur was wegschreibst, wenn sich der Kurs geändert hat ...

LG,

track

Antworten |