ubuntuusers.de

BashScript zum Webscraping von Verkehrsinfos

Status: Ungelöst | Ubuntu-Version: Ubuntu 20.04 (Focal Fossa)
Antworten |

mybasher

Anmeldungsdatum:
8. Juli 2022

Beiträge: Zähle...

Hallo Leute, ich bräuchte bitte Hilfe zu meinem Bashscript. Es sollen die Verkehrsinfos von einer Seite aus dem Internet per Webscraping geholt werden (funktioniert bereits) und dann diese in regelmäßigen Abständen immer wieder abgeglichen werden. Gab es Änderungen sollen diese Infos per SIGNAL an eine Handynummer verschickt werden. Ich habe Probleme damit, dass die Erkennung, ob es neue Verkehrsinfos gibt bei mir nicht funktioniert.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
!/bin/bash
# Es sollen die aktuellen Verkehrsinfos abgeholt und per SIGNAL Messenger verteilt werden

LOGFILE="/var/log/myVERKEHR.log"
#$DIFF beinhaltet den COUNTstart als Zahl
DIFF="/var/log/myVERKEHRdiff.txt"
#
COUNTDIFF="/var/log/myVERKEHRcountdiff.txt"
#SIGNAL_BINARY=/opt/signal-cli-0.10.6/bin/signal-cli
SIGNAL_BINARY=/home/pi/signal_rpi/signal-cli-0.9.0/bin
RUFNUMMERN="+49xxx"
URL="https://www.bayernwelle.de/verkehrsservice"
COUNTINIT=0
touch $LOGFILE
stunde=$(date '+%H')
minute=$(date '+%M')


function StartCounter {
        touch $DIFF
        curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' > $DIFF
        echo "Habe Datei $DIFF angelegt."
        echo ""
        cat $DIFF
        # Zeilenanzahl in Datei speichern
        COUNTstart=$(cat $DIFF | wc -l)
        echo "$COUNTstart" > $COUNTDIFF
        echo ""
        echo "StartCounter in $COUNTDIFF geschrieben."

}

#Erster Aufruf
function DiffDa {
# check ob die Datei $DIFF existiert
if [[ -f $DIFF ]]
then
        echo "Datei $DIFF ist da."
        # Ins Logfile fortlaufend schreiben

        echo "`date`:  " >> $LOGFILE
        echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1 >> $LOGFILE
        curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' >> $LOGFILE
        echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> $LOGFILE
else
#       touch $DIFF
#       curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' > $DIFF
#       echo "Habe Datei angelegt."
#       cat $DIFF
#       # Zeilenanzahl in Datei speichern
#       COUNTstart=$(cat $DIFF | wc -l)
#       echo "$COUNTstart" > $COUNTDIFF
#       echo "und weg."
        exit
fi
}

function  main {
# Ins Logfile fortlaufend schreiben
COUNT2=$(cat $DIFF | wc -l)
echo "aktueller Counter - COUNT2: $COUNT2"


#Counter aus Datei lesen
read COUNTstart < $COUNTDIFF
echo "CounterSTART: $COUNTstart"

#Counter vergleichen
if [ $COUNTstart -eq $COUNT2 ];
then
        echo "nichts machen"
#       cat $LOGFILE
else
        echo "Hole die aktuellen Verkehrsinfos und versende per SIGNAL"
        # Ins Logfile fortlaufend schreiben
        echo "`date`:  " >> $LOGFILE
        echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> $LOGFILE
        curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' >> $LOGFILE
       curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' | signal-cli --verbose send>
        echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> $LOGFILE
fi

}

 
#main:
# von 5:30 bis 20 Uhr
if test $stunde -eq 5 -a $minute -ge 30 -o $stunde -le 20 -a $stunde -ge 8 ; 
then
        clear
        echo "führe Skript aus"
        DiffDa
        StartCounter
        main

else
        echo "jetzt nicht ausführen und aufräumen"
        rm $LOGFILE
        rm $DIFF
fi
exit

shiro Team-Icon

Supporter

Anmeldungsdatum:
20. Juli 2020

Beiträge: 1270

Hallo mybasher,

du machst doch kein diff. Woher soll das Script dann wissen, was zu tun ist? Ich habe dein Script mal als eine Zeile formuliert (den "signal-cli" in ein "mutt" umgesetzt um eine eMail zu erhalten) und dies als "cron" job (kannst natürlich aus ein systemd timer verwenden) getestet.

curl -s https://www.bayernwelle.de/verkehrsservice | html2markdown | sed -n '/Blitzer/,/Baustellen/p' | tee /tmp/new.txt | diff - /tmp/old.txt >/dev/null && (echo gleich $? >>/tmp/old.txt) || (cat /tmp/new.txt | mutt -s "Blitzer in Bayern" user@domain.de ); mv /tmp/new.txt /tmp/old.txt

Die Mail-Adresse muss natürlich angepasst werden bzw durch deine "signal-cli" SMS Aktion ersetzt werden. Zeitfenster und Intervall kannst du ja im crontab bzw systemd timer einstellen.

PS: Dein html2text hatte ich nicht installiert und daher das mit python3 mitgelieferte "html2markdown" verwendet.

PS2: Wenn dich die vielen Leerzeilen und die letzte Zeile stören, kannst du statt

  • (cat /tmp/new.txt | mutt ... auch besser

  • (sed '/^$/d;$d' /tmp/new.txt | mutt ... schreiben.

mybasher

(Themenstarter)

Anmeldungsdatum:
8. Juli 2022

Beiträge: 3

Hallo Shiro, dankeschön. Ich werde es morgen gleich mal testen.

mybasher

(Themenstarter)

Anmeldungsdatum:
8. Juli 2022

Beiträge: 3

Ich habe meinen Code jetzt soweit angepasst. Allerdings scheint etwas mit dem diff nicht zu passen, da er es jedes mal ausführt.

Was macht eigentlich "diff -" ?

Ehrlich gesagt, verstehe ich den Part mit dem diff nicht.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
        touch $DIFF
        curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' | tee $DIFF | diff - $DIFF2 >/dev/null && (echo gleich $? >> $DIFF2)

        echo "Habe die Datei $DIFF angelegt."
        echo ""
        echo "Hole die aktuellen Blitzer und versende per SIGNAL"
        cat $DIFF | signal-cli --verbose send $RUFNUMMERN
        # Ins Logfile fortlaufend schreiben
        echo "`date`:  " >> $LOGFILE
        echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> $LOGFILE
        curl -s $URL | html2text -utf8 | sed -n '/Blitzer/,$p' | sed -n '/Baustellen/q;p' >> $LOGFILE
        echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> $LOGFILE
        mv $DIFF $DIFF2

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13205

mybasher schrieb:

Was macht eigentlich "diff -" ?

Liest eine der beiden Argumente aus Stdin.

Ehrlich gesagt, verstehe ich den Part mit dem diff nicht.

Das erscheint mir auch nicht sinnvoll: $DIFF2 wird einmal verwendet, um mit der aktuellen Ausgabe der Kette curl ... sed zu vergleichen und dann wird in die Datei "gleich $?" geschrieben, wobei $? das Ergebnis des Vergleichs (0 für "gleich", andere Werte für "verschieden") beinhaltet. Das sind zwei total verschiedene Dinge.

Man könnte auch noch mehr quoten, um z.B. Probleme mit Shell-Meta-Zeichen in $URL zu vermeiden. Ich würde auch $LOGFILE nicht ständig öffnen, sondern das so machen:

1
2
3
exec 9>>"$LOGFILE"

echo "$(date):  " >&9

Das vermeidet einerseits, dass die Datei ständig geöffnet werden muss (was nicht übermäßig teuer ist). Zum zweiten stellt es sicher, dass alle Ausgaben dieses einen Skript-Laufes in derselben Datei landen. Das kann passieren, wenn die Logdatei woanders hin verschoben wird, während das Skript läuft.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Alternativ kann man auch die Ausgaben von kompletten Blöcken umleiten, also z.B.:

1
2
3
4
{
    echo "foo bar"
    echo "blah fahsel"
} > "$LOGFILE"

Das ist oft weniger Aufwand als für jede Zeile eine Umleitung anzugeben oder eine extra Funktion zu definieren, die Argumente in die gewünschte Datei schreibt.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13205

seahawk1986 schrieb:

Alternativ kann man auch die Ausgaben von kompletten Blöcken umleiten, also z.B.:

Das ist oft weniger Aufwand als für jede Zeile eine Umleitung anzugeben oder eine extra Funktion zu definieren, die Argumente in die gewünschte Datei schreibt.

Klar, funktioniert allerdings nicht so gut, wenn man es selektiv machen will - also, nicht alle Ausgaben nach Stdout in die Datei schicken. Und selbst in dem Fall kann man das auch mit exec machen und spart sich die Klammer (und Einrückung):

1
2
3
4
exec >"$LOGFILE"

echo "foo bar"
echo "blah fahsel"

Ich finde das auch etwas lesbarer, insbesondere, wenn das Skript lang ist. Man sieht dann schon gleich oben, wohin alle Ausgaben wandern und übersieht nicht die Umleitung irgendwo am Ende des Skriptes.

Antworten |