Frage von ralphdieter, 12

Wie sammle ich täglich Zahlen von einer Website?

Auf einer Internetseite stehen ein paar tagesaktuelle Zahlen. Ich möchte diese sammeln und später statistisch auswerten.

Das geht zwar recht billig mit "wget | grep | sed >> Statistik", aber die Formatierung (z.B. als CSV-Datei) lässt dabei noch Wünsche offen. Aktuell habe ich folgendes Script für crontab:

( date  +'%n%Y-%m-%d %H:%M' && echo -n "Punkte: " && 
  ( wget -q -O- <a href="http://www.gutefrage.net/nutzer/ralphdieter">www.gutefrage.net/nutzer/ralphdieter</a> |
    grep -A2 'Punkte</span>'|tail -1|sed 's: *::;s:</span>::'
  ) &&
  ( wget -q -O- <a href="http://www.gutefrage.net/nutzer/ralphdieter">www.gutefrage.net/nutzer/ralphdieter</a> |
    grep '"UserProfileOverview-fact....."' |
    sed 'N;s/\n//;s/ *<span class="UserProfileOverview-fact.....">//g;s:</span>:\t:g'
  )
) >> /home/ralphdieter/gf-statistik

Ein Datensatz sieht damit so aus:

2016-03-18 13:50
Punkte: 16.059                              
136 Hilfr. Antw.    
876 Antworten   
5   Fragen  
7   Freunde 
105 Komplim.    
238 Danke   

Um das in LibreOffice zu laden, braucht's aber noch viel Nacharbeit. Mit einem zweiten Durchlauf von sed krieg ich das zwar auch noch hin, aber lieber wär's mir, wenn alles gleich in einem Rutsch passieren würde, etwa in der Form:

2016-03-18 13:50;16.059;136;876;5;7;105;238;

Gibt es irgendwelche Tools, die mir das Leben hier leichter machen?

Hilfreichste Antwort - ausgezeichnet vom Fragesteller
von TeeTier, 4

Sorry, dass ich gleich zwei Antworten verfasse, aber mir hat deine Frage keine Ruhe gelassen, und ich bin jetzt bei folgendem 7-Zeiler gelandet:

test -f stats.csv || echo 'hilfr;antw;fragen;freunde;kompl;punkte;datum' >> stats.csv

wget -qO- http://www.gutefrage.net/nutzer/ralphdieter \
| grep -ioP '(^\s{30,}|UserProfileOverview-factCount">)\K\d+(\.\d+)?(?=\s*)' \
| head -n7 \
| sed 's_\.__g' \
| tr '\n' ';' >> stats.csv

date >> stats.csv

Wie du siehst, alles in einem Rutsch. :)

Der reguläre Ausdruck benutzt \K von Perl für positives Lookbehind, da dieses dynamisch ist und nicht mit (?<=...) funktionieren wird.

Dank head werden nur die ersten 7 Zeilen betrachtet, und möglicher Mist der danach kommt abgeschnitten. Die sed-Zeile ist nötig dafür, dass der Punkt aus formatierten Zahlen verschwindet, sodass also aus "12.345" einfach nur "12345" wird. (Du willst die Daten ja schließlich später noch weiter verarbeiten, oder?)

Drei mal kurz hintereinander aufgerufen, ergibt sich folgende Ausgabe:

hilfr;antw;fragen;freunde;kompl;danke;punkte;datum
136;885;6;7;105;242;16174;Sun Mar 20 05:16:34 CET 2016
136;885;6;7;105;242;16174;Sun Mar 20 05:16:37 CET 2016
136;885;6;7;105;242;16174;Sun Mar 20 05:16:39 CET 2016

Sogar schick mit Spaltenüberschriften! Na, wenn das mal kein Luxus ist! ;)

Wenn du das Skript über cron alle paar Stunden aufrufst, ändern sich die Zahlen logischerweise. Im Abstand von wenigen Sekunden - wie im obigen Beispiel - passiert da natürlich nichts. :)

Das einzige "Problem" ist jetzt, dass die Reihenfolge nicht mehr so ist, wie in deiner Fragestellung. Falls das für die spätere Verarbeitung tatsächlich relevant sein sollte, das Ganze einfach durch diesen awk-Einzeiler laufen lassen:

awk '-F;' \
'{print $8";"$7";"$1";"$2";"$3";"$4";"$5";"$6}' \
stats.csv > alternativ.csv

Dann kommst du im Endeffekt auf dieses Ergebnis:

datum;punkte;hilfr;antw;fragen;freunde;kompl;danke
Sun Mar 20 05:16:34 CET 2016;16174;136;885;6;7;105;242
Sun Mar 20 05:16:37 CET 2016;16174;136;885;6;7;105;242
Sun Mar 20 05:16:39 CET 2016;16174;136;885;6;7;105;242

Also dann ... viel Spaß damit und einen schönen Tag noch! :)

Kommentar von ralphdieter ,

Genial! "grep -P" wurde vermutlich in Hogwards entwickelt. Das hinter dem \K hab' ich zwar nicht ganz verstanden, aber '\K[\d\.]+' erfüllt den Zweck für mich genauso.

Und das Datum hinten dranhängen hat echt was! Jetzt muss ich über meinen eigenen Versuch schmunzeln.

So kann ich es getrost ein paar Monate laufen lassen. Und mein anderes Script (für die globale GF-Statistik) werde ich auch gleich vereinfachen.

Vielen Dank!

Antwort
von TeeTier, 4

Nimm doch awk statt sed. Aber ein bisschen Umfang lässt sich dabei leider nicht vermeiden.

Ich habe meinen GF-Crawler in Python geschrieben, weil der erste Versuch mit bash, wget, sed, grep, awk, tr, usw. ausartete.

Vielleicht lohnt es sich in deinem Fall auch, auf Perl, Ruby oder Python umzusteigen. Shellskripte sind zwar enorm praktisch, aber sie werden schnell hässlich, wenn der Umfang zunimmt.

Noch ein kleiner Hinweis im Bezug auf GF: Die Bezeichner im Quelltext und die innere Struktur ändern sich so alle 9 Monate mal spontan, ohne dass man beim betrachten der Website einen Unterschied feststellen wird. Außerdem blockiert GF gängige HTTP-Libs, sodass du auf jeden Fall einen plausiblen User-Agent-String setzen solltest. Wenn da irgendwo "Java x.y.z" oder "Python x.y" steht, bekommst du einen 403er Fehlercode.

Außerdem ist GF so verbuggt, dass einige Seiten manchmal völlig OHNE Response-Header zurück kommen. Die Antwort fängt dann direkt mit "<!DOCTYPE ..." an. Gängige Browser sind an solche Schrott-Server gewöhnt, und versuchen die Seite dann trotzdem bis zum Ende mit "</html>" zu laden, aber erstens kommen gängige HTTP-Libs damit nicht klar, und zweitens musst du da unbedingt drauf achten, falls du deine eigene HTTP-Lib implementierst.

Bei mir war am Ende eine vollständige Eigenentwicklung der Weg des geringsten Widerstands, da ich noch viele andere Dinge damit mache, und sowohl wget, als auch Pythons http-Modul mir zu wenig Kontrolle bieten.

Naja, viel Spaß noch mit deiner Statistik! :)

PS: Generierst du die Diagramme danach mit gnuplot, oder benutzt du etwas anderes?

Kommentar von ralphdieter ,

Ich habe meinen GF-Crawler in Python geschrieben, weil der erste Versuch mit bash, wget, sed, grep, awk, tr, usw. ausartete.

Endlich einer, der mich versteht! Eigentlich wollte ich doch nur mal schnell...

am Ende eine vollständige Eigenentwicklung

Genau das will ich vermeiden. Ich will doch nur schnell... :-) Am liebsten wäre mir dafür ein "apt-get install gf-crawler".

Generierst du die Diagramme danach mit gnuplot

Nö: Ich importiere die Werte in Access und bereite sie dann mit PowerPoint auf :-)

Antwort
von Linuxhase, 4

Hallo

Das geht zwar recht billig mit "wget | grep | sed >> Statistik",

Kann dann so aussehen:

#!/bin/bash
# gfstats.sh

DATUM=$(date +'%n%Y-%m-%d %H:%M')
VAR=$(wget -q -O- www.gutefrage.net/nutzer/ralphdieter|grep "factCount")

echo ${DATUM} # Datum
echo "${VAR}"|head -n1|cut -d '>' -f2|cut -d '<' -f1 # Punkte
echo "${VAR}"|head -n2|tail -n1|cut -d'>' -f2|cut -d'<' -f1 # Hilfreiche Antworten
echo "${VAR}"|head -n3|tail -n1|cut -d'>' -f2|cut -d'<' -f1 # Fragen
echo "${VAR}"|head -n4|tail -n1|cut -d'>' -f2|cut -d'<' -f1 # Freunde
echo "${VAR}"|head -n5|tail -n1|cut -d'>' -f2|cut -d'<' -f1 # Komplimente
echo "${VAR}"|head -n6|tail -n1|cut -d'>' -f2|cut -d'<' -f1 # Danke

Was ist denn daran auszusetzen?

aber die Formatierung (z.B. als CSV-Datei) lässt dabei noch Wünsche offen.

Na und, dann so

#!/bin/bash
# gfstats.sh

DATUM=$(date +'%n%Y-%m-%d %H:%M')
VAR=$(wget -q -O- www.gutefrage.net/nutzer/ralphdieter|grep "factCount")

PKT=$(echo "${VAR}"|head -n1|cut -d '>' -f2|cut -d '<' -f1) # Punkte
HANT=$(echo "${VAR}"|head -n2|tail -n1|cut -d'>' -f2|cut -d'<' -f1) # Hilfreiche Antworten
FRAG=$(echo "${VAR}"|head -n3|tail -n1|cut -d'>' -f2|cut -d'<' -f1) # Fragen
FRED=$(echo "${VAR}"|head -n4|tail -n1|cut -d'>' -f2|cut -d'<' -f1) # Freunde
KOMP=$(echo "${VAR}"|head -n5|tail -n1|cut -d'>' -f2|cut -d'<' -f1) # Komplimente
DKE=$(echo "${VAR}"|head -n6|tail -n1|cut -d'>' -f2|cut -d'<' -f1) # Danke

echo ${DATUM},${PKT},${HANT},${FRAG},${FRED},${KOMP},${DKE}

Wenn Dir dann die Kommata nicht Recht sind, dann so:

bash gfstats.sh|sed 's/,/;/g' >> gf-statistik

und schon kannst Du es überall importieren.

Linuxhase

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten