Webscraping mit Raspberry Pi – Teil 2 – Beautifulsoup

Von jeder Website, die aufgerufen werden kann, können auch Daten extrahiert werden. Manche Websiten bieten APIs an, um eine direkte Schnittstelle zu haben. Wenn so etwas nicht existiert, kommt „Webscraping“ zum Zuge. Webscraping heisst, dass Daten direkt aus dem Quelltext einer HTML-Seite extrahiert werden.

Da in diesem Tutorial mit Beautifulsoup gearbeitet werden soll, muss eine HTML-Website angesteuert werden. Javascript kann mit BeautifulSoup4 nicht verwendet werden. Hierfür gibt es andere Möglichkeiten (Selenium).

Welche Daten möchte ich haben?

Meine Frau und ich haben schon lange die Vermutung, dass wir morgens im Bad immer wieder dieselben Lieder im Radio hören. Ich möchte herausfinden, ob dies nur eine subjektive Empfindung ist, oder sogar objektiv feststellbar ist.

BeiRadio Bremenvier gibt es eine Tabelle, auf der die zuletzt gespielten Lieder vom Radiosender Bremen4 angezeigt und ständig aktualisiert werden. Die Tabelle ist im HTML code recht einfach zu finden.

  • Das Element der Tabelle, dessen Informationen ich abspeichern möchte, markieren und Rechtsklick für „Element untersuchen (z.B. im Browser Chrome)
  • Tabellen auf Websites werden mit dem <table> – Tag eingeleitet und mit </table> geschlossen. Innerhalb der Tabellen wird mittels <tr> die Reihe und mit <td> die Spalte bzw. Zelle der Reihe definiert. Mich interessiert nur der erste Song-Eintrag in der Tabelle. Dieser ist innterhalb der zweiten Reihe der Tabelle zu finden. In der ersten Reihe stehen die Überschriften der Spalte.
<tr class="top44_table_line1">
		<td class="top44_table_zelle left bottom">14:23</td>
		<td class="top44_table_zelle  bottom">Smith,Sam</td>
		<td class="top44_table_zelle right bottom">I'm not the only one</td>
	</tr>

An dem Quellcode-Ausschnitt wird deutlich, dass die interessierende Tabellenreihe das Attribut class=“top44_table_line1“ enhält. Alle Informationen die innerhalb dieses <tr>-Tags sind, will ich haben.

Python Code mit Beautifulsoup
Untenstehend ist der Python-Code, der genutzt wird, um die Radiosongs (d.h. Uhrzeit, Künstler, Titel) von der Website zu scrapen. Da die Uhrzeit von der Website kein Datum enthält, ergänze ich Jahr, Monat und Tag über ein Python-Package.
Ich beschreibe kurz, was der untere Code macht. Als erstes wird die Arbeitsumgebung geschaffen, indem die Module geladen werden. Dann wird ein leeres Objekt erstellt, dass ich später benötige.
Anschließend wird eine Endlosschleife gestartet, die alle zwei Minuten durchläuft. Zuerst wird die Website abgefragt und als Beautifulsoup-Objekt abgelegt. Beautifulsoup wird nun angewiesen in den festgelegten Zellen der HTML-Tabelle nach Informationen zu suchen und diese in eine Datei abzulegen. Jedoch nur, wenn der neue Eintrag nicht derselbe wie der alte ist. Anschließend wartet das Programm zwei Minuten, um anschließend von vorne loszulegen. Die „Else“ Bedingung tritt z.B. dann in Kraft, wenn keine Information auf der HTML-Website zu finden war. Dies ist – wie ich herausfand – Nachts von 0:00 bis 6:00 morgens der Fall, da Bremenvier um diese Zeit keine eigenen Lieder sendet, sondern von einem anderen Sender der RadioBremen-Gruppe übernimmt.

Den Code habe ich übrigens während einer „ONOC – Open Night of Coding“ an der Uni-Bremen geschrieben. Wie ihr seht, ist der Code allerdings nicht besonders lang, weshalb meine ONOC eher eine „OHOC – Open Hour of Coding“ war 😉

#Importieren der Module
import requests
import time
import datetime
from bs4 import BeautifulSoup

# leeren Wert fuer den Titelvergleich erstellen, da dieser beim ersten Durchlauf noch nicht existiert
last=""

#Endlosschleife starten
while (True):
    try:
        #Website aufrufen und als soup-objekt nutzbar machen
        fobj = open("daten.dat","a")
        r  = requests.get("http://www.radiobremen.de/bremenvier/musik/titelsuche/index.html")
        data = r.text
        soup = BeautifulSoup(data)
        
        #Gesuchte Informationen werden als Objekt gespeichert          
        line1= soup.select('tr.top44_table_line1 > td')[0]
        line2= soup.select('tr.top44_table_line1 > td')[1]
        line3= soup.select('tr.top44_table_line1 > td')[2]
        now = datetime.datetime.now().strftime("%y-%m-%d")            
        entry="{Artist:s}\t{Song:s}\t{Zeit:s}\t{Datum}".format(Zeit=line1.text,Artist=line2.text,Song=line3.text,Datum=now)
        print(entry)
        
        #Abgleich, ob bei der Abfrage noch dasselbe Lied läuft wie bei der letzten Abfrage, wenn nicht wird das neue Lied eingetragen und ein neuer Wert für den Titelvergleich definiert
        if last != entry:
                fobj.write(entry + "\n")
                last=entry
                fobj.close()      
        time.sleep(120)
               
    except:
        print("Did not find any data")

Auf dem Raspberry Pi findet sich anschließend eine Datei namens „daten.dat“, in der eine Tabulatorseparierte Liste von Einträgen steht.