BeautifulSoup
๐๐ฒ ๐๐ฉ๐ฉ๐ฌ ๐๐ซ๐ ๐ง๐จ๐ญ ๐๐๐๐ง๐๐จ๐ง๐ฐ๐๐ซ๐!
Yesterday, #RitterRadar got some updates: first, all dependencies were refreshed (no more CVEs); then I fixed some bugs I had noticed over the past few weeks; and finally, the best news: a new feature that gives you a copyable list of the events matching your current filter.
So, for instance, if you live near Potsdam and want to see all medieval events within 50 km over the next two months – you get this:
——-
04. Juli 2026 | Kinder- und Sommerfest in Gannahall 2026 | 14641 Nauen (26 km)
04. Juli 2026 – 05. Juli 2026 | Mythologie und Handwerk des Mittelalters 2026 | 15569 Woltersdorf (47 km)
22. Aug. 2026 – 23. Aug. 2026 | Sommerfest Lรผbarser Hofkulturdiverse Konzerte | 13469 Berlin (30 km)
29. Aug. 2026 | Mittelalterliches zum Ackerbรผrgerfest | 14641 Nauen (26 km)
——-
#FastAPI #WebScraping #OpenStreetMap #Geocoding #OpenSource #EventDiscovery
URL to the GitHub-project: https://github.com/marcelpetrick/RitterRadarย if you haven’t given it a try yet โ๏ธ๐
โ๏ธ๐ ๐ฅ๐ถ๐๐๐ฒ๐ฟ๐ฅ๐ฎ๐ฑ๐ฎ๐ฟ ๐ก๏ธ๐ฐ๐
๐๐ฆ๐ข๐ณ๐ฌ๐ฆ๐ฏ, ๐จ๐ฐ๐ฐ๐ฅ ๐ต๐ณ๐ข๐ท๐ฆ๐ญ๐ญ๐ฆ๐ณ, ๐ข๐ฏ๐ฅ ๐ญ๐ฆ๐ฏ๐ฅ ๐ต๐ฉ๐ช๐ฏ๐ฆ ๐ฆ๐ข๐ณ!
๐๐ช๐ต๐ต๐ฆ๐ณ๐๐ข๐ฅ๐ข๐ณ ๐ช๐ด ๐ข ๐ค๐ถ๐ฏ๐ฏ๐ช๐ฏ๐จ ๐ช๐ฏ๐ด๐ต๐ณ๐ถ๐ฎ๐ฆ๐ฏ๐ต, ๐ง๐ฐ๐ณ๐จ๐ฆ๐ฅ ๐ช๐ฏ ๐ต๐ฉ๐ฆ ๐ง๐ช๐ณ๐ฆ๐ด ๐ฐ๐ง ๐๐บ๐ต๐ฉ๐ฐ๐ฏ, ๐ต๐ฐ ๐ข๐ช๐ฅ ๐ต๐ฉ๐ฆ๐ฆ ๐ช๐ฏ ๐ต๐ฉ๐บ ๐ฏ๐ฐ๐ฃ๐ญ๐ฆ ๐ฒ๐ถ๐ฆ๐ด๐ต: ๐ต๐ฉ๐ฆ ๐ฅ๐ช๐ด๐ค๐ฐ๐ท๐ฆ๐ณ๐บ ๐ฐ๐ง ๐ฎ๐ฆ๐ฅ๐ช๐ฆ๐ท๐ข๐ญ ๐ฎ๐ข๐ณ๐ฌ๐ฆ๐ต๐ด, ๐๐ฆ๐ฏ๐ข๐ช๐ด๐ด๐ข๐ฏ๐ค๐ฆ ๐ง๐ข๐ช๐ณ๐ด, ๐๐ช๐ฌ๐ช๐ฏ๐จ ๐ด๐ฑ๐ฆ๐ค๐ต๐ข๐ค๐ญ๐ฆ๐ด, ๐ข๐ฏ๐ฅ ๐๐ฉ๐ณ๐ช๐ด๐ต๐ฎ๐ข๐ด ๐ณ๐ฆ๐ท๐ฆ๐ญ๐ณ๐ช๐ฆ๐ด ๐ฐ๐ง ๐ต๐ฉ๐ฆ ๐ข๐ฏ๐ค๐ช๐ฆ๐ฏ๐ต ๐ด๐ต๐บ๐ญ๐ฆ – ๐ข๐ค๐ณ๐ฐ๐ด๐ด ๐ต๐ฉ๐ฆ ๐๐ฆ๐ณ๐ฎ๐ข๐ฏ ๐ญ๐ข๐ฏ๐ฅ๐ด ๐ข๐ฏ๐ฅ ๐ฃ๐ฆ๐บ๐ฐ๐ฏ๐ฅ.
๐๐ฉ๐ช๐ด ๐ต๐ฐ๐ฐ๐ญ ๐ฅ๐ฐ๐ต๐ฉ ๐ฅ๐ช๐ด๐ฑ๐ข๐ต๐ค๐ฉ ๐ต๐ช๐ณ๐ฆ๐ญ๐ฆ๐ด๐ด ๐ธ๐ฆ๐ฃ-๐ค๐ณ๐ข๐ธ๐ญ๐ช๐ฏ๐จ ๐ข๐จ๐ฆ๐ฏ๐ต๐ด ๐ช๐ฏ๐ต๐ฐ ๐ต๐ฉ๐ฆ ๐ท๐ข๐ด๐ต ๐ฅ๐ช๐จ๐ช๐ต๐ข๐ญ ๐ธ๐ช๐ญ๐ฅ๐ฆ๐ณ๐ฏ๐ฆ๐ด๐ด. ๐๐ฉ๐ฆ๐บ ๐ณ๐ฆ๐ต๐ถ๐ณ๐ฏ ๐ญ๐ข๐ฅ๐ฆ๐ฏ ๐ธ๐ช๐ต๐ฉ ๐ต๐ช๐ฅ๐ช๐ฏ๐จ๐ด ๐ฐ๐ง ๐ง๐ฐ๐ณ๐ต๐ฉ๐ค๐ฐ๐ฎ๐ช๐ฏ๐จ ๐ฆ๐ท๐ฆ๐ฏ๐ต๐ด – ๐ต๐ฉ๐ฆ๐ช๐ณ ๐ฏ๐ข๐ฎ๐ฆ๐ด, ๐ต๐ฉ๐ฆ๐ช๐ณ ๐ฅ๐ข๐ต๐ฆ๐ด, ๐ต๐ฉ๐ฆ๐ช๐ณ ๐ธ๐ฉ๐ฆ๐ณ๐ฆ๐ข๐ฃ๐ฐ๐ถ๐ต๐ด โ ๐ข๐ฏ๐ฅ ๐ด๐ต๐ฐ๐ณ๐ฆ ๐ข๐ญ๐ญ ๐ธ๐ช๐ต๐ฉ๐ช๐ฏ ๐ข ๐ญ๐ฐ๐ค๐ข๐ญ ๐ต๐ณ๐ฆ๐ข๐ด๐ถ๐ณ๐บ ๐ฐ๐ง ๐๐๐๐ช๐ต๐ฆ.
๐๐ฑ๐ฐ๐ฏ ๐ต๐ฉ๐ช๐ฏ๐ฆ ๐ฐ๐ธ๐ฏ ๐ฎ๐ข๐ค๐ฉ๐ช๐ฏ๐ฆ ๐ช๐ต ๐ฅ๐ฐ๐ต๐ฉ ๐ณ๐ฆ๐ฏ๐ฅ๐ฆ๐ณ ๐ข ๐ฎ๐ฐ๐ด๐ต ๐ฃ๐ฆ๐ข๐ถ๐ต๐ช๐ง๐ถ๐ญ ๐ช๐ฏ๐ต๐ฆ๐ณ๐ข๐ค๐ต๐ช๐ท๐ฆ ๐ฎ๐ข๐ฑ, ๐ธ๐ฉ๐ฆ๐ณ๐ฆ๐ถ๐ฑ๐ฐ๐ฏ ๐ต๐ฉ๐ฐ๐ถ ๐ฎ๐ข๐บ๐ฆ๐ด๐ต ๐ณ๐ถ๐น๐๐ฒ๐ฟ ๐ฏ๐ ๐ฝ๐ฒ๐ฟ๐ถ๐ผ๐ฑ (๐ธ๐ฉ๐ช๐ค๐ฉ ๐ฎ๐ฐ๐ฏ๐ต๐ฉ๐ด ๐ต๐ฉ๐ฐ๐ถ ๐ธ๐ช๐ด๐ฉ๐ฆ๐ด๐ต ๐ต๐ฐ ๐ด๐ถ๐ณ๐ท๐ฆ๐บ) ๐ข๐ฏ๐ฅ ๐ณ๐ถ๐น๐๐ฒ๐ฟ ๐ฏ๐ ๐๐ฝ๐ฎ๐ฐ๐ฒ (๐ต๐ฉ๐บ ๐ฉ๐ฐ๐ฎ๐ฆ ๐ฑ๐ฐ๐ด๐ช๐ต๐ช๐ฐ๐ฏ ๐ข๐ฏ๐ฅ ๐ข ๐ณ๐ข๐ฅ๐ช๐ถ๐ด ๐ฐ๐ง ๐ต๐ฉ๐บ ๐ค๐ฉ๐ฐ๐ฐ๐ด๐ช๐ฏ๐จ, ๐ง๐ณ๐ฐ๐ฎ ๐ข ๐ด๐ต๐ฐ๐ฏ๐ฆ’๐ด ๐ต๐ฉ๐ณ๐ฐ๐ธ ๐ต๐ฐ 1024 ๐ญ๐ฆ๐ข๐จ๐ถ๐ฆ๐ด). ๐๐ญ๐ช๐ค๐ฌ ๐ถ๐ฑ๐ฐ๐ฏ ๐ข๐ฏ๐บ ๐ฎ๐ข๐ณ๐ฌ๐ฆ๐ณ ๐ต๐ฐ ๐ญ๐ฆ๐ข๐ณ๐ฏ ๐ต๐ฉ๐ฆ ๐ง๐ถ๐ญ๐ญ ๐ฑ๐ข๐ณ๐ต๐ช๐ค๐ถ๐ญ๐ข๐ณ๐ด. ๐๐ฉ๐ฆ ๐ค๐ณ๐ข๐ธ๐ญ๐ฆ๐ณ ๐ณ๐ถ๐ฏ๐ฏ๐ฆ๐ต๐ฉ ๐ช๐ฏ ๐ต๐ฉ๐ฆ ๐ฃ๐ข๐ค๐ฌ๐จ๐ณ๐ฐ๐ถ๐ฏ๐ฅ; ๐ต๐ฉ๐ฆ ๐ฎ๐ข๐ฑ ๐ณ๐ฆ๐ง๐ณ๐ฆ๐ด๐ฉ๐ฆ๐ต๐ฉ ๐ฐ๐ฏ ๐ช๐ต๐ด ๐ฐ๐ธ๐ฏ ๐ข๐ค๐ค๐ฐ๐ณ๐ฅ.
๐๐ฐ ๐ค๐ญ๐ฐ๐ถ๐ฅ. ๐๐ฐ ๐ข๐ค๐ค๐ฐ๐ถ๐ฏ๐ต๐ด. ๐๐ฐ ๐ฅ๐ข๐ต๐ข ๐ญ๐ฆ๐ข๐ท๐ฆ๐ต๐ฉ ๐ต๐ฉ๐บ ๐ฎ๐ข๐ค๐ฉ๐ช๐ฏ๐ฆ. ๐๐ฉ๐ถ๐ด: ๐ข ๐ฉ๐ฆ๐ญ๐ฑ๐ฆ๐ณ ๐ต๐ฐ๐ฐ๐ญ ๐ต๐ฉ๐ข๐ต ๐ค๐ณ๐ข๐ธ๐ญ๐ฆ๐ต๐ฉ ๐ต๐ฉ๐ฆ ๐ธ๐ฆ๐ฃ ๐ธ๐ช๐ต๐ฉ ๐ค๐ถ๐ด๐ต๐ฐ๐ฎ ๐ค๐ณ๐ข๐ธ๐ญ๐ฆ๐ณ๐ด, ๐ฑ๐ณ๐ฆ๐ด๐ฆ๐ฏ๐ต๐ฆ๐ต๐ฉ ๐ต๐ฉ๐ฆ ๐ง๐ช๐ฏ๐ฅ๐ช๐ฏ๐จ๐ด, ๐ข๐ฏ๐ฅ ๐ข๐ญ๐ญ๐ฐ๐ธ๐ฆ๐ต๐ฉ ๐ต๐ฉ๐ฆ๐ฆ ๐ต๐ฐ ๐ด๐ช๐ง๐ต ๐ต๐ฉ๐ฆ๐ฎ ๐ฃ๐บ ๐ต๐ช๐ฎ๐ฆ ๐ข๐ฏ๐ฅ ๐ฃ๐บ ๐ฅ๐ช๐ด๐ต๐ข๐ฏ๐ค๐ฆ. ๐๐ฐ๐ต๐ฉ๐ช๐ฏ๐จ ๐ฎ๐ฐ๐ณ๐ฆ, ๐ฏ๐ฐ๐ต๐ฉ๐ช๐ฏ๐จ ๐ญ๐ฆ๐ด๐ด – ๐ฃ๐ถ๐ต ๐ง๐ข๐ด๐ฉ๐ช๐ฐ๐ฏ๐ฆ๐ฅ ๐ธ๐ช๐ต๐ฉ ๐ค๐ข๐ณ๐ฆ.
——-
Also: Wir besuchen recht gerne Mittelaltermรคrkte. Jetzt ist es so, dass die Schaustellergruppen umherziehen beziehungsweise bestimmte Events an historischen Orten stattfinden. Ich wohne nicht an einem historischen Ort.
Also sucht man eine der vielen Seiten im Netz auf, die Termine auflisten. Diese sind รผber die Jahre gewachsen, und viele Seiten bieten auch Komfortfunktionen wie โFilter nach Datum oder Bundeslandโ an, aber:
* ๐๐ฟ๐ฎ๐ด๐บ๐ฒ๐ป๐๐ถ๐ฒ๐ฟ๐๐ป๐ด: Nicht alle Seiten zeigen โalle Eventsโ
* Ein Filter nach Bundesland hat das Problem, dass man alles einzeln sichten muss, wenn man auch gewillt ist, Landesgrenzen zu รผberschreiten (oder eben ungefiltert, yada yada)
* ๐๐ถ๐น๐๐ฒ๐ฟ๐๐ป๐ด ๐ป๐ฎ๐ฐ๐ต ๐ญ๐ฒ๐ถ๐๐ฟ๐ฎ๐๐บ (Vergangenes interessiert mich nicht)
Also, wie man sieht: ein komplexer Task, wenn man sich einen Plan fรผr die nรคchsten Monate machen mรถchte. Durchaus lรถsbar, aber wie Clarence Bleicher sagt: โ[..] ๐๐ต๐ฎ๐ ๐๐ต๐ฒ๐ป ๐ต๐ฒ ๐ต๐ฎ๐ฑ ๐ฎ ๐ต๐ฎ๐ฟ๐ฑ ๐ท๐ผ๐ฏ, ๐ต๐ฒ ๐๐ผ๐๐น๐ฑ ๐ฎ๐๐๐ถ๐ด๐ป ๐ถ๐ ๐๐ผ ๐ฎ โ๐น๐ฎ๐๐ ๐บ๐ฎ๐ปโ ๐ฏ๐ฒ๐ฐ๐ฎ๐๐๐ฒ ๐๐ต๐ฒ๐ ๐๐ผ๐๐น๐ฑ ๐ณ๐ถ๐ป๐ฑ ๐ฎ๐ป ๐ฒ๐ฎ๐๐ ๐๐ฎ๐ ๐๐ผ ๐ฑ๐ผ ๐ถ๐.โ โ kein Job fรผr mich ๐
Nun bin ich auch KEIN Webentwickler. Aber das sollte mich nicht daran hindern, โRitter Radarโ zu entwickeln.
Eine App, die aus mehreren Webcrawlern sowie Front- und Backend besteht. Alle bekannten Mittelaltermarkt-Seiten werden durchsucht, die Ergebnisse kommen in eine lokale Datenbank, und dann hat man die Mรถglichkeit, in einem Web-UI nach Entfernung zum Startort und Zeitraum zu filtern. Easy peasy.
BeautifulSoup, OpenStreetMap, Python, SQLite, Uvicorn, ein bisschen HTML und CSS … und fertig.
Ich habe es bisher nicht auf ein Web-Deployment getrimmt, weil ich die Arbeit der Ersteller der Mittelaltermarkt-Seiten honoriere. Wenn ich jetzt so ein Portal hosten wรผrde, wรคre ich wie Google mit den KI-Suchergebnissen: Eine Zusammenfassung drรคngt sich zwischen Nutzer und Ersteller und fรคngt so Webseiten-Traffic ab.
Daher: Einfach auf https://github.com/marcelpetrick/RitterRadar das Repository klonen und selbst bootstrappen: zwei Shell-Skripte ausfรผhren, fertig ist der Lack. โ๏ธ๐
simple webscraper for last.fm with BeautifulSoup
tl;dr:
Simple webscraper with Python and BeautifulSoup for one user’s favorite tracks (‘loved songs’) at last.fm.
Repository: github
full text:
Looks like last.fm is shutting down its services (one feature at at time, lol). They started this process more or less ten years ago.
I’ve realized that I would miss my curated list of favorite tracks and I am also very bad at remembering, so … let’s automate the process of grabbing that information from their public page. I know, they offer a REST API, but I wanted to use once BS4.
Since I had somehow two free hours fourteen days ago, I went full-speed to some tutorials, played with the get-requests and how to parse. And then spent the last minutes parsing the received “artist+track”-string into something usable. Alltogether four hours were spent and I am amazed by the result. Of course, by leveraging three quite powerful libraries (beautifulsoup4, requests, lxml) and skipping TDD (;) I’ve reached the goal quite fast. And since the script works (my 1500 loved songs are scraped in less than 60 seconds), I will also not spend additional effort to make it “pretty”.

