Last active
August 13, 2021 09:52
-
-
Save behackl/65fcc82e9a66e5f1b94b8ce482110017 to your computer and use it in GitHub Desktop.
Scraper for available vaccination dates in the Uppsala region
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This is a utility bot parsing the available vaccination slots | |
in Uppsala's region and sending changes whenever new vaccination | |
dates become available to a (Discord) webhook. | |
I've put this together during a train ride, so don't expect | |
well-documented code. It has helped me to get a suitable | |
vaccination date, and as such it has done its job well. | |
Python dependencies are beautifulsoup4 and timeloop. | |
Made with <3 by @behackl. Feel free to use and adapt it | |
– or don't. | |
""" | |
import bs4 | |
import requests | |
from timeloop import Timeloop | |
from datetime import timedelta | |
tl = Timeloop() | |
discord_webhook = "https://discord.com/api/webhooks/<insert stuff here>" | |
page = "https://vaccinationsbokning.regionuppsala.se/" | |
last_report = None | |
@tl.job(interval=timedelta(seconds=60)) | |
def parse_available_slots(): | |
global last_report | |
response = requests.get(page) | |
if response.status_code != 200: | |
requests.post(discord_webhook, {"content": f"Error parsing {page}, status code {response.status_code}"}) | |
return | |
page_content = bs4.BeautifulSoup(response.content) | |
timeslot_containers = page_content.find_all("div", {"class": "timeslot-area"}) | |
region_timeslots = dict( | |
(slot.find_previous("h3").text.strip(), | |
dict( | |
(s.find("p").text, | |
s.find("div", {"class": "timeslot-availibility"}).text.strip() | |
) for s in slot.find_all("div", {"class": "timeslot"}))) for slot in timeslot_containers | |
) | |
for center, slots in region_timeslots.items(): | |
for day in slots.keys(): | |
capacity = 0 if slots[day] == "Fullbokat" else int(slots[day].split()[0]) | |
slots[day] = capacity | |
available_slots = dict((center, dict((day, capacity) for day, capacity in slots.items() if capacity > 0)) for center, slots in region_timeslots.items()) | |
available_slots = dict((center, slots) for center, slots in available_slots.items() if slots) | |
available_slots_simple = dict((center, set(slots.keys())) for center, slots in available_slots.items()) | |
if available_slots_simple != last_report: | |
msg = "**Change in available vaccinations!**\n\n" | |
msg += "\n".join([f"*{c}*: { ', '.join(f'{d} ({cap})' for d, cap in s.items()) }" for c, s in available_slots.items()]) | |
msg += "\n\n<https://vaccinationsbokning.regionuppsala.se/#Uppsala>" | |
available_dates = set.union(*[set(s.keys()) for s in available_slots.values()]) | |
requests.post(discord_webhook, {"content": msg}) | |
last_report = available_slots_simple | |
print(last_report) | |
if __name__ == "__main__": | |
tl.start(block=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment