From 91ab8dfaeda0d344d8903e94b98d05379896d42e Mon Sep 17 00:00:00 2001 From: rang01 <61165035+rang01@users.noreply.github.com> Date: Wed, 4 Mar 2020 00:07:41 +0100 Subject: [PATCH] Add files via upload Added new city Marburg with geojson file --- park_api/cities/Marburg.geojson | 148 ++++++++++++++++++++++++++++++++ park_api/cities/Marburg.py | 76 ++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 park_api/cities/Marburg.geojson create mode 100644 park_api/cities/Marburg.py diff --git a/park_api/cities/Marburg.geojson b/park_api/cities/Marburg.geojson new file mode 100644 index 0000000..e4bdcb7 --- /dev/null +++ b/park_api/cities/Marburg.geojson @@ -0,0 +1,148 @@ +{ + "type": "FeatureCollection", + "features": [{ + "type": "Feature", + "geometry": { + "type": "Point", + "coordinates": [ + 8.2168987, + 53.1391840 + ] + }, + "properties": { + "name": "Marburg", + "type": "city", + "url": "https://pls.marburg.de/", + "source": "https://www.marburg-tourismus.de/portal/seiten/parken-900000695-1000000.html", + "active_support":false + } + }, { + "type": "Feature", + "properties": { + "name": "Ahrens", + "total": 225, + "address": "Wilhelmstraße 7", + "type": "Parkhaus" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.35665, + 46.05613 + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Erlenring-Center", + "total": 50, + "address": "Erlenring 19", + "type": "Parkhaus" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.47756, + 46.65494 + ] + } + }, , + { + "type": "Feature", + "properties": { + "name": "Furthstraße", + "total": 204, + "address": "Furthstraße 6", + "type": "Parkhaus" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 49.07525, + 46.25178 + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Hauptbahnhof", + "total": 288, + "address": "Krummbogen 3", + "type": "Parkhaus" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 49.08410, + 46.46899 + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Lahncenter", + "total": 168, + "address": "Pilgrimstein 29", + "type": "Tiefgarage" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.59200, + 46.36928 + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Marktdreieck", + "total": 280, + "address": "Erlenring 26", + "type": "Parkhaus" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.41966, + 46.65171 + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Marktdreieck - Parkdeck", + "total": 20, + "address": "Musterstraße 2", + "type": "Parkplatz" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.41966, + 46.65171 + ] + } + }, + { + "type": "Feature", + "properties": { + "name": "Oberstadt", + "total": 235, + "address": "Pilgrimmstein 4", + "type": "Parkhaus" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 48.63934, + 46.29220 + ] + } + }, + ] +} diff --git a/park_api/cities/Marburg.py b/park_api/cities/Marburg.py new file mode 100644 index 0000000..74993ca --- /dev/null +++ b/park_api/cities/Marburg.py @@ -0,0 +1,76 @@ + +import requests +from bs4 import BeautifulSoup as soup +import re +from park_api.util import convert_date +from park_api.geodata import GeoData + +# This loads the geodata for this city if .geojson exists in the same directory as this file. +# No need to remove this if there's no geodata (yet), everything will still work. +geodata = GeoData(__file__) + +# source url https://pls.marburg.de/ +my_url = ('https://pls.marburg.de/') + +# Gesamtanzahl der Parkplätze: https://www.marburg.de/smartcity/10/03/01/index.html +# unter dem link gibt es weitere Parkplätze ohne aktuelle Informationen und die Gesamtkapazität + +# store page in var +r = requests.get(my_url) + +# parse the html-page in the var using an html parser of the beautiful soup package +page_soup = soup(r.text, "html.parser") + + +# This function is called by the scraper and given the data of the page specified as source in geojson above. +# It's supposed to return a dictionary containing everything the current spec expects. Tests will fail if it doesn't ;) +def parse_html(html): + + # BeautifulSoup is a great and easy way to parse the html and find the bits and pieces we're looking for. + soup = BeautifulSoup(html, "html.parser") + + # last_updated is the date when the data on the page was last updated, it should be listed on most pages + last_updated = convert_date(fetch_day[0] + " " + fetch_time[0], '%d.%m.%Y %H:%M:%S') + + # Regulärer Ausdruck für das Datum: [0-3][0-9].[0-9][0-9].20[0-9][0-9] + fetch_day = re.findall("[0-3][0-9].[0-9][0-9].20[0-9][0-9]", str(page_soup.body.text)) + + # Reulärer Ausdruck für die Uhrzeit: [0-2][0-9]:[0-5][0-9]:[0-9][0-9] + fetch_time = re.findall("[0-2][0-9]:[0-5][0-9]:[0-9][0-9]", str(page_soup.body.text)) + + data = { + # convert_date is a utility function you can use to turn this date into the correct string format + "last_updated": convert_date(last_updated, "%d.%m.%Y %H:%M Uhr"), + # URL for the page where the scraper can gather the data + "lots": [] + } + + for row in page_soup.table.find_all("tr"): + cells = row.find_all("td") + if len(cells) == 4: + lot_name = re.sub("\s+-\s+geschlossen", "", cells[0].text) + lot_name = re.sub("[\n\t]+", "", lot_name) + + lot_name = re.sub(" +", " ", lot_name) + lot_free = int(re.sub("[^0-9]", "", cells[1].text) or 0) + + if "geschlossen" in cells[0].text: + state = 'closed' + else: + state = 'open' + + lot = geodata.lot(lot_name) + data["lots"].append({ + "name": lot.name, + "free": lot_free, + "total": lot_total, + "address": lot.address, + "coords": lot.coords, + "state": state, + "lot_type": lot.type, + "id": lot.id, + "forecast": False, + }) + + return data +