Ich betreibe mit Logic Moon ein eigenes Label. Jedes Release landet zuerst auf Bandcamp, danach überall sonst. Spotify, Apple Music, Deezer, Amazon Music, SoundCloud, Beatport. Um nicht bei jedem Release sechsmal manuell zu suchen, hab ich jahrelang Odesli benutzt, besser bekannt als Songlink. Ein Link rein, alle Plattform-Links raus.
Jetzt ist der Dienst tot. Oder zumindest so instabil, dass ich mich nicht mehr drauf verlassen will.
Also hab ich mir gedacht: dann bau ich mir das eben selbst.
Die Ausgangslage: einfacher als gedacht, komplizierter als gedacht
Die Idee ist simpel. Bandcamp-URL rein, Künstler und Titel rausziehen, auf den anderen Plattformen suchen, das beste Ergebnis nehmen, als JSON ausspucken. Ein Nachmittagsprojekt, dachte ich.
Es wurde eine Woche.
Der erste Prototyp mit Playwright stand schnell. Bandcamp-Seite scrapen, die strukturierten Daten (JSON-LD) auslesen, Künstler und Titel extrahieren. Danach für jede Plattform die Suche öffnen, Ergebnisse einsammeln, mit Fuzzy-Matching (Titel-/Artist-Ähnlichkeit) den besten Treffer picken.
Lief. Auf dem Papier.
Bug Nummer 1: Der Fake-Match, der niemandem aufgefallen wäre
Beim ersten echten Testlauf gegen mein eigenes Katalog fiel mir was auf: Apple Music fand für ein Release namens “Atlas” ein komplett anderes Album von einem komplett anderen Künstler. Mit 93 Prozent Konfidenz.
Der Grund war fies. Wenn der Scraper den Artist-Namen aus dem HTML nicht sauber extrahieren konnte, fiel der Code auf den gesuchten Artist zurück, statt das Feld einfach leer zu lassen. Das Ergebnis: Ein völlig falscher Treffer bekam automatisch einen perfekten Artist-Match vorgetäuscht, weil der Code sich selbst belogen hat.
Acht von zehn Plattform-Modulen hatten genau diesen Bug. Copy-paste macht’s möglich.
Der Fix war ein Einzeiler pro Datei. Der Fund war der eigentliche Wert der Übung: ein Scraper, der leise falsche Ergebnisse liefert, ist gefährlicher als einer, der gar keine liefert.
Bug Nummer 2: Ein Zeichen hat alles verändert
Der nervigste Bug der ganzen Woche: Apple Music fand für dasselbe Release bei jedem Aufruf ein anderes, falsches Ergebnis. Mal passte es, mal nicht. Kein erkennbares Muster.
Nach Stunden Debugging der Unterschied: Mein Code hat Leerzeichen in der Such-URL als + kodiert. Der Browser eines Menschen kodiert sie als %20. Beides ist technisch korrekt. Beides sollte dasselbe bedeuten.
Apple Music hat aus dem + und dem %20 zwei unterschiedliche Suchanfragen mit unterschiedlichem Ranking gemacht.
Kein Timeout, kein leeres Ergebnis, kein Fehler. Nur ein plausibel aussehendes, falsches Ergebnis. Genau die Art Bug, die man nie findet, wenn man nicht zufällig denselben Query zweimal testet und sich wundert, warum die Ergebnisse unterschiedlich sind.
Bug Nummer 3: Wenn beide Antworten richtig aussehen
Bei SoundCloud wird ein Album oder EP oft als “Set” abgelegt, technisch eine Playlist mit eigener URL. Mein Scraper fand aber konsequent den einzelnen Track statt des Sets, selbst wenn beides existierte.
Der naheliegende Fix: Sets bevorzugen, wenn einer gefunden wird. Klang gut, bis ich es gegen den ganzen Katalog getestet habe. Ergebnis: Ein Set eines völlig anderen Künstlers gewann plötzlich gegen den korrekten Track, nur weil “Glow” zufällig Teil eines fremden Album-Titels war.
Die unbequeme Erkenntnis: Manchmal gibt es keinen sauberen Algorithmus, der zwei plausible Antworten zuverlässig trennt. Ich hab mich am Ende für die Variante entschieden, die nie einen falschen Treffer produziert, auch wenn sie dafür manchmal die hübschere URL verpasst.
Was am Ende steht
Ein Python-Tool, das aus einer Bandcamp-URL heraus systematisch auf sechs Plattformen sucht und die Treffer mit einem Konfidenz-Wert zurückgibt. Kein Blackbox-Ergebnis, sondern nachvollziehbares JSON: gefunden, nicht gefunden, und mit welcher Sicherheit.
Nicht jede Plattform lässt sich zuverlässig scrapen. YouTube Music blockt anonyme Anfragen hinter einer Cookie-Consent-Wall, die sich (noch) nicht sauber automatisieren lässt. Tidal liefert für Suchanfragen ohne Login praktisch nichts brauchbares. Beide Module sind fertig geschrieben und liegen im Repo bereit, nur eben aktuell deaktiviert, bis sich das ändert oder mir eine bessere Lösung einfällt.
Und ehrlich: Das ist auch okay. Ein Tool, das ehrlich sagt “hier bin ich mir nicht sicher”, ist besser als eins, das bei jeder Anfrage optimistisch irgendwas zurückgibt.
Warum ich das teile
Weil jeder, der ein eigenes Label oder eine Künstlerseite betreibt, irgendwann vor demselben Problem steht: Ein zentraler Dienst, auf den man sich verlassen hat, verschwindet einfach. Und die Alternative ist entweder wieder manuell sechs Tabs öffnen, oder sich selbst was bauen.
Der Code liegt komplett offen auf GitHub, inklusive der ganzen Debugging-Geschichte im Commit-Verlauf. Wer selbst Bandcamp-Releases über mehrere Plattformen hinweg tracken will, findet dort den kompletten Scraper zum Forken und Anpassen.
Manchmal ist der beste Fix für einen toten Dienst nicht, auf den nächsten zu warten. Sondern selbst nachzubauen, was man wirklich braucht.
Kommentare