# download latest PDF d = sc.pdfdownload(pdf_url, raw=True, silent=True) # extract case numbers reported for previous days d = d.replace(u'\xa0', u' ') # data from the most recent press release dd = sc.DayData(canton='FL', url=pdf_url) dd.datetime = sc.find(r'Situationsbericht vom (.*? 20\d{2})', d) dd.cases = sc.find(r'insgesamt\s+([0-9]+)\s+laborbestätigte\s+Fälle', d) m = re.search(r'Bisher\s+trat(en)?\s+(\S+)\s+(Todesfall|Todesfälle)', d, flags=re.I) if m: dd.deaths = sc.int_or_word(m[2]) if re.search( 'Alle\s+weiteren\s+Erkrankten\s+sind\s+in\s+der\s+Zwischenzeit\s+genesen', d): dd.recovered = int(dd.cases) - int(dd.deaths) print(dd) # get the data from PDF file containing full history history_url = 'https://www.llv.li/files/ag/aktuelle-fallzahlen.pdf' d = sc.pdfdownload(history_url, layout=True, silent=True) for row in d.splitlines(): m = re.search( r'^(?:Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag|Sonntag),\s+(.+\d{4})\s+(\d+)$', row)
content) dd.deaths = sc.find( r'(Damit\s+traten\s+)?(?:bisher|bislang)\s+(traten\s+)?(?P<death>\d+)\s+(Todesfall|Todesfälle)', content, flags=re.I, group='death') if re.search( r'Alle\s+weiteren\s+Erkrankten\s+sind\s+in\s+der\s+Zwischenzeit\s+genesen', content): dd.recovered = int(dd.cases) - int(dd.deaths) m = re.search(r'(\S+)\s+Erkrankte\s+sind\s+derzeit\s+hospitalisiert', content) if m: dd.hospitalized = sc.int_or_word(m[1].lower()) m = re.search( r'Gegenwärtig\s+befinden\s+sich\s+(\w+)\s+enge\s+Kontaktpersonen\s+in\s+Quarantäne.', content) if m: dd.quarantined = sc.int_or_word(m[1]) if dd: if not is_first: print('-' * 10) print(dd) is_first = False # get the data from PDF file containing full history history_url = 'https://www.llv.li/files/ag/aktuelle-fallzahlen.pdf'
d, flags=re.I) if m: dd.cases = int(m[2]) else: dd.cases = int( sc.find( 'Die\s*Zahl\s*der\s*(\d+)\s*Infektionen\s*setzt\s*sich.*?zusammen\s*aus', d)) m = re.search( r'Aktuell\s*befinden\s*sich\s*(\S+)\s*Einwohnerinnen\s*und\s*Einwohner\s*des\s*Kantons\s*Basel-Stadt\s*aufgrund\s*einer\s*Covid-19-Infektion\s*in\s*Spitalpflege\s*in\s*einem\s*baselstädtischen\s*Spital\.\s*Total\s*sind\s*(?:dies|es)\s*(\S+)\s*Personen', d, flags=re.I) if m: bs_residents = sc.int_or_word(m[1]) dd.hospitalized = sc.int_or_word(m[2]) dd.hosp_non_resident = dd.hospitalized - bs_residents else: dd.hospitalized = sc.int_or_word( sc.find('wovon\s*(\S+)\s*im\s*Spital sind', d) or sc.find( r'Von\s+den\s+aktiven\s+Fällen\s+befinden\s+sich\s+(\S+)\s+Personen\s+in\s+Spitalpflege', d)) dd.recovered = sc.find(r'\b([0-9]+)\s*Personen\s*der\s*[0-9]+\s*positiv\s*Getesteten\s*.+\s*sind\s*wieder\s*genesen', d) or \ sc.find('(\d+) genesenen Personen', d) dd.icu = sc.int_or_word( sc.find(r'Insgesamt\s*(\S+)\s*Personen benötigen\s*Intensivpflege', d)) dd.deaths = sc.find(r'Basel-Stadt\s*verzeichnet\s*unverändert\s*([0-9]+)\s*Todesfälle', d) or \ sc.find(r'Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt(?:\s*\S+)?\s*insgesamt\s*([0-9]+)\b', d) or \
url = f'{base_url}/daten?id=28177' d = sc.download(url, silent=True) soup = BeautifulSoup(d, 'html.parser') xls_url = soup.find('a', href=re.compile(r'.*\.xlsx')).get('href') if not xls_url.startswith('http'): xls_url = f'{base_url}{xls_url}' xls = sc.xlsdownload(xls_url, silent=True) rows = sc.parse_xls(xls, header_row=3) total_cases = 0 total_deaths = 0 is_first = True for row in rows: dd = sc.DayData(canton='LU', url=xls_url) dd.datetime = row['Datum'] dd.cases = sc.int_or_word(row['Neue\xa0Fälle']) if dd.cases: total_cases += dd.cases dd.cases = total_cases dd.deaths = sc.int_or_word(row['Verstorbene']) if dd.deaths: total_deaths += dd.deaths dd.deaths = total_deaths dd.hospitalized = sc.int_or_word(row['Hospitalisierte']) dd.vent = sc.int_or_word(row['Beatmete']) dd.isolated = sc.int_or_word(row['In\xa0Isolation']) dd.quarantined = sc.int_or_word(row['In\xa0Quarantäne']) dd.quarantine_riskareatravel = sc.int_or_word(row['Reiserückkehrer\xa0in\xa0Quarantäne']) if dd: if not is_first: print('-' * 10)
url = f'{base_url}/daten?id=28177' d = sc.download(url, silent=True) soup = BeautifulSoup(d, 'html.parser') xls_url = soup.find('a', href=re.compile(r'.*\.xlsx')).get('href') if not xls_url.startswith('http'): xls_url = f'{base_url}{xls_url}' xls = sc.xlsdownload(xls_url, silent=True) rows = sc.parse_xls(xls, header_row=5) total_cases = 0 total_deaths = 0 is_first = True for row in rows: dd = sc.DayData(canton='LU', url=xls_url) dd.datetime = row['Datum'] dd.cases = sc.int_or_word(row.search(r'Neue\s+Fälle')) if dd.cases: total_cases += dd.cases dd.cases = total_cases dd.deaths = sc.int_or_word(row['Verstorbene']) if dd.deaths: total_deaths += dd.deaths dd.deaths = total_deaths dd.hospitalized = sc.int_or_word(row['Total']) dd.vent = sc.int_or_word(row.search(r'davon\s+beatmet')) dd.isolated = sc.int_or_word(row.search(r'in\s+Isolation')) dd.quarantined = sc.int_or_word(row.search(r'in\s+Quarantäne')) dd.quarantine_riskareatravel = sc.int_or_word(row.search(r'Reiserückkehrer\s+in\s+Quarantäne')) if dd: if not is_first: print('-' * 10)
# Use non-greedy matching. print('Date and time:', sc.find(r'Stand\s*[A-Za-z]*,?\s*(.+?),\s*(?:liegen\s*)?insgesamt', d)) m = re.search(r'Bisher\s*sind\s*die\s*Tests\s*von\s*([0-9]+)\s*Personen\s*positiv\s*ausgefallen\s*\(inklusive\s*der\s*([0-9]+)\s*Basler\s*Fälle\)', d, flags=re.I) if m: # print('Confirmed cases (residents):', int(m[2])) # print('Confirmed cases (non-residents):', int(m[1]) - int(m[2])) # print('Confirmed cases (all):', int(m[1])) print('Confirmed cases:', int(m[2])) # Residents only. else: print('Confirmed cases:', sc.find(r'(?:insgesamt\s*)?([0-9]+)\s*positive', d)) print('WARNING: Main pattern for matching confirmed cases numbers failed to match', file=sys.stderr) m = re.search(r'Aktuell\s*befinden\s*sich\s*([0-9]+)\s*Einwohnerinnen\s*und\s*Einwohner\s*des\s*Kantons\s*Basel-Stadt\s*aufgrund\s*einer\s*Covid-19-Infektion\s*in\s*Spitalpflege\s*in\s*einem\s*baselstädtischen\s*Spital\.\s*Total\s*sind\s*(?:dies|es)\s*([0-9]+)\s*Personen', d, flags=re.I) if m: # print('Hospitalized (non-residents):', int(m[2]) - int(m[1])) # print('Hospitalized (residents):', int(m[1])) # print('Hospitalized (all):', int(m[2])) print('Hospitalized:', int(m[2])) # Irrespective of residency. else: print('WARNING: Main pattern for matching hospitalized numbers failed to match', file=sys.stderr) print('Recovered:', sc.find(r'\b([0-9]+)\s*Personen\s*der\s*[0-9]+\s*positiv\s*Getesteten\s*.+\s*sind\s*wieder\s*genesen', d)) print('ICU:', sc.int_or_word(sc.find(r'Insgesamt\s*(\S+)\s*Personen benötigen\s*Intensivpflege', d))) print( 'Deaths:', sc.find(r'Basel-Stadt\s*verzeichnet\s*unverändert\s*([0-9]+)\s*Todesfälle', d) or sc.find(r'Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt(?:\s*\S+)?\s*insgesamt\s*([0-9]+)\b', d) or sc.find(r'Die\s*Zahl\s*der\s*Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt\s*unverändert\s*([0-9]+)\b', d) )
# 2020-05-29 """ Die Zahl der 978 Infektionen setzt sich zusammen aus 923 genesenen Personen, 50 Todesfällen und fünf aktiven Fällen in Isolation (+ 2), wovon zwei im Spital sind. In Quarantäne befinden sich aktuell drei Personen (+ 3). Die Zahl der Todesfälle im Kanton Basel-Stadt beträgt seit dem 30. April 2020 unverändert 50. """ dd.datetime = sc.find(r'Stand\s*[A-Za-z]*,?\s*(.+\s+(:?Uhr)?),\s*(?:liegen\s*)?(?:insgesamt\s*)?', d) m = re.search(r'Bisher\s*sind\s*die\s*Tests\s*von\s*([0-9]+)\s*Personen.*\s*positiv\s*ausgefallen\s*\(inklusive\s*der\s*([0-9]+)\s*Basler\s*Fälle\)', d, flags=re.I) if m: dd.cases = int(m[2]) else: dd.cases = sc.find('Die\s*Zahl\s*der\s*(\d+)\s*Infektionen\s*setzt\s*sich\s*zusammen\s*aus', d) m = re.search(r'Aktuell\s*befinden\s*sich\s*(\S+)\s*Einwohnerinnen\s*und\s*Einwohner\s*des\s*Kantons\s*Basel-Stadt\s*aufgrund\s*einer\s*Covid-19-Infektion\s*in\s*Spitalpflege\s*in\s*einem\s*baselstädtischen\s*Spital\.\s*Total\s*sind\s*(?:dies|es)\s*(\S+)\s*Personen', d, flags=re.I) if m: dd.hospitalized = sc.int_or_word(m[2]) else: dd.hospitalized = sc.int_or_word(sc.find('wovon\s*(\S+)\s*im\s*Spital sind', d)) dd.recovered = sc.find(r'\b([0-9]+)\s*Personen\s*der\s*[0-9]+\s*positiv\s*Getesteten\s*.+\s*sind\s*wieder\s*genesen', d) or \ sc.find('(\d+) genesenen Personen', d) dd.icu = sc.int_or_word(sc.find(r'Insgesamt\s*(\S+)\s*Personen benötigen\s*Intensivpflege', d)) dd.deaths = sc.find(r'Basel-Stadt\s*verzeichnet\s*unverändert\s*([0-9]+)\s*Todesfälle', d) or \ sc.find(r'Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt(?:\s*\S+)?\s*insgesamt\s*([0-9]+)\b', d) or \ sc.find(r'Die\s*Zahl\s*der\s*Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt\s*.*unverändert\s*([0-9]+)\b', d) dd.isolated = sc.int_or_word(sc.find(r'\s+(\S+)\s+aktiven\s+Fällen', d)) dd.quarantined = sc.find(r'In\s+Quarantäne\s+befinden\s+sich\s+aktuell\s+(\d+)\s+Personen', d) print(dd)
# 2020-04-14 """ <div class="text"> <p>Mit Stand Dienstag, 14. April 2020, 10 Uhr, liegen insgesamt 899 positive Fälle von Personen mit Wohnsitz im Kanton Basel-Stadt vor. Dies sind sechs mehr als am Vortag. 663 Personen der 899 positiv Getesteten und damit über 70 Prozent sind wieder genesen. Die Zahl der Todesfälle im Kanton Basel-Stadt beträgt unverändert 34.</p> <p>Im Kanton Basel-Stadt werden nebst den Tests der Kantonsbewohnerinnen und -bewohner auch Tests von Verdachtsfällen aus anderen Schweizer Kantonen und dem grenznahen Ausland durchgeführt. Bisher sind die Tests von 1389 Personen positiv ausgefallen (inklusive der 899 Basler Fälle).</p> <p>Aktuell befinden sich 61 Einwohnerinnen und Einwohner des Kantons Basel-Stadt aufgrund einer Covid-19-Infektion in Spitalpflege in einem baselstädtischen Spital. Total sind es 86 Personen (inklusive ausserkantonale und ausländische Patientinnen und Patienten). Insgesamt 9 Personen benötigen Intensivpflege. Die anderen Patientinnen und Patienten befinden sich auf der normalen Station.</p> </div> """ dd.datetime = sc.find(r'Stand\s*[A-Za-z]*,?\s*(.+\s+(:?Uhr)?),\s*(?:liegen\s*)?(?:insgesamt\s*)?', d) m = re.search(r'Bisher\s*sind\s*die\s*Tests\s*von\s*([0-9]+)\s*Personen\s*positiv\s*ausgefallen\s*\(inklusive\s*der\s*([0-9]+)\s*Basler\s*Fälle\)', d, flags=re.I) if m: dd.cases = int(m[2]) m = re.search(r'Aktuell\s*befinden\s*sich\s*([0-9]+)\s*Einwohnerinnen\s*und\s*Einwohner\s*des\s*Kantons\s*Basel-Stadt\s*aufgrund\s*einer\s*Covid-19-Infektion\s*in\s*Spitalpflege\s*in\s*einem\s*baselstädtischen\s*Spital\.\s*Total\s*sind\s*(?:dies|es)\s*([0-9]+)\s*Personen', d, flags=re.I) if m: dd.hospitalized = int(m[2]) dd.recovered = sc.find(r'\b([0-9]+)\s*Personen\s*der\s*[0-9]+\s*positiv\s*Getesteten\s*.+\s*sind\s*wieder\s*genesen', d) dd.icu = sc.int_or_word(sc.find(r'Insgesamt\s*(\S+)\s*Personen benötigen\s*Intensivpflege', d)) dd.deaths = sc.find(r'Basel-Stadt\s*verzeichnet\s*unverändert\s*([0-9]+)\s*Todesfälle', d) or \ sc.find(r'Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt(?:\s*\S+)?\s*insgesamt\s*([0-9]+)\b', d) or \ sc.find(r'Die\s*Zahl\s*der\s*Todesfälle\s*im\s*Kanton\s*Basel-Stadt\s*beträgt\s*unverändert\s*([0-9]+)\b', d) print(dd)
dd.cases = sc.find(r"insgesamt\s+([0-9]+)\s+laborbestätigte\s+Fälle", d) dd.deaths = sc.find( r'(Damit\s+traten\s+)?(?:bisher|bislang)\s+(traten\s+)?(?P<death>\d+)\s+(Todesfall|Todesfälle)', d, flags=re.I, group='death') if re.search( 'Alle\s+weiteren\s+Erkrankten\s+sind\s+in\s+der\s+Zwischenzeit\s+genesen', d): dd.recovered = int(dd.cases) - int(dd.deaths) m = re.search(r'(\S+)\s+Erkrankte\s+sind\s+derzeit\s+hospitalisiert', d) if m: dd.hospitalized = sc.int_or_word(m[1].lower()) m = re.search( r'Gegenwärtig\s+befinden\s+sich\s+(\d+)\s+enge\s+Kontaktpersonen\s+in\s+Quarantäne.', d) if m: dd.quarantined = m[1] if dd: print(dd) is_first = False else: print("WARNING: PDF URL not found (Situationsbericht)", file=sys.stderr) # get the data from PDF file containing full history history_url = 'https://www.llv.li/files/ag/aktuelle-fallzahlen.pdf'
# extract case numbers reported for previous days d = d.replace(u'\xa0', u' ') d = d.replace("'", "") d = d.replace("’", "") # data from the most recent press release dd = sc.DayData(canton='FL', url=pdf_url) dd.datetime = sc.find(r'Situationsbericht vom (.*? 20\d{2})', d) dd.cases = sc.find(r"insgesamt\s+([0-9]+)\s+laborbestätigte\s+Fälle", d) m = re.search( r'(?:Bisher|Bislang)\s+trat(en)?\s+(\S+)\s+(Todesfall|Todesfälle)', d, flags=re.I) if m: dd.deaths = sc.int_or_word(m[2]) if re.search( 'Alle\s+weiteren\s+Erkrankten\s+sind\s+in\s+der\s+Zwischenzeit\s+genesen', d): dd.recovered = int(dd.cases) - int(dd.deaths) m = re.search(r'(\S+)\s+Erkrankte\s+sind\s+derzeit\s+hospitalisiert', d) if m: dd.hospitalized = sc.int_or_word(m[1].lower()) m = re.search( r'Gegenwärtig\s+befinden\s+sich\s+(\d+)\s+enge\s+Kontaktpersonen\s+in\s+Quarantäne.', d) if m: dd.quarantined = m[1]