Files
aki_prj23_transparenzregister/Jupyter/API-tests/Bundesanzeiger/notebook.ipynb

69 KiB

Daten Extraktion aus dem Bundesanzeiger

Vorbereitung

In [77]:
import pandas as pd

from aki_prj23_transparenzregister.utils.data_extraction.bundesanzeiger import (
    Bundesanzeiger,
)

ba_wrapper = Bundesanzeiger()
# df_reports = ba_wrapper.get_information("Törmer Energy Solar 1 GmbH & Co. KG", "")
# df_reports = ba_wrapper.get_information("Atos IT-Dienstleistung und Beratung GmbH", "")
df_reports = ba_wrapper.get_information(
    "Stadtwerke Haltern am See Gesellschaft mit beschränkter Haftung", ""
)
df_reports.head()
Out[77]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </style>
date company raw_report jahr auditors financial_results
1 2022-10-21 Stadtwerke Haltern am See Gesellschaft mit bes... <div class="publication_container">\n <div cla... 2021 [Auditor(name='Volker Voelcker', company='Pric... {'revenue': 46275.0, 'net_income': 1757.0, 'eb...
3 2021-10-12 Stadtwerke Haltern am See Gesellschaft mit bes... <div class="publication_container">\n <div cla... 2020 [Auditor(name='Hubert Ahlers', company='Pricew... {'revenue': 47459.0, 'net_income': 1661.0, 'eb...
5 2020-12-03 Stadtwerke Haltern am See Gesellschaft mit bes... <div class="publication_container">\n <div cla... 2019 [Auditor(name='Hubert Ahlers', company='Pricew... {'revenue': 45575.0, 'net_income': 1599.0, 'eb...
6 2020-01-09 Stadtwerke Haltern am See Gesellschaft mit bes... <div class="publication_container">\n <div cla... 2018 [Auditor(name='Hubert Ahlers', company='Pricew... {'revenue': 43898.0, 'net_income': 2043.0, 'eb...
7 2019-10-10 Stadtwerke Haltern am See Gesellschaft mit bes... <div class="publication_container">\n <div cla... 2017 [] {}

Daten Extraktion

In [78]:
from bs4 import BeautifulSoup
from io import StringIO
In [79]:
sample_report = df_reports.iloc[1].raw_report

Aufsichtsrat

TODO

Bilanz bzw. GuV

In [80]:
def parse_tables(report: str) -> list:
    result = []
    soup = BeautifulSoup(report, features="html.parser")
    for table in soup.find_all("table", {"class": "std_table"}):
        df = pd.read_html(StringIO(str(table)), flavor="bs4")[0]
        print(df.columns)
        print(df.dtypes)
        result.append(df)
    return result


tables = parse_tables(sample_report)
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                 'T€'),
            (              '2019',                 'T€'),
            (       'Veränderung',                 'T€'),
            (       'Veränderung',                  '%')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1     object
2020                T€                    float64
2019                T€                    float64
Veränderung         T€                      int64
                    %                       int64
dtype: object
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                 'T€'),
            (              '2020',                  '%'),
            (              '2019',                 'T€'),
            (              '2019',                  '%'),
            (     'Veränderungen',                 'T€'),
            (     'Veränderungen',                  '%')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1     object
2020                T€                    float64
                    %                       int64
2019                T€                    float64
                    %                       int64
Veränderungen       T€                    float64
                    %                       int64
dtype: object
MultiIndex([('Unnamed: 0_level_0', 'gerundet'),
            (              '2020',       'T€'),
            (              '2019',       'T€'),
            (       'Veränderung',       'T€'),
            (       'Veränderung',        '%')],
           )
Unnamed: 0_level_0  gerundet     object
2020                T€          float64
2019                T€          float64
Veränderung         T€          float64
                    %             int64
dtype: object
MultiIndex([('Unnamed: 0_level_0', 'unkonsolidiert gerundet'),
            (              '2020',                      'T€'),
            (              '2019',                      'T€'),
            (       'Veränderung',                      'T€'),
            (       'Veränderung',                       '%')],
           )
Unnamed: 0_level_0  unkonsolidiert gerundet     object
2020                T€                         float64
2019                T€                         float64
Veränderung         T€                         float64
                    %                            int64
dtype: object
MultiIndex([('Jahresüberschuss/Jahresfehlbetrag nach Betriebszweigen', ...),
            (                                                  '2020', ...),
            (                                                  '2019', ...),
            (                                           'Veränderung', ...),
            (                                           'Veränderung', ...)],
           )
Jahresüberschuss/Jahresfehlbetrag nach Betriebszweigen  Unnamed: 0_level_1     object
2020                                                    T€                    float64
2019                                                    T€                    float64
Veränderung                                             T€                      int64
                                                        %                       int64
dtype: object
Index(['Unnamed: 0', '2020  T€', '2019  T€'], dtype='object')
Unnamed: 0     object
2020  T€      float64
2019  T€      float64
dtype: object
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            ( '31. Dezember 2020',                 'T€'),
            ( '31. Dezember 2020',                  '%'),
            ( '31. Dezember 2019',                 'T€'),
            ( '31. Dezember 2019',                  '%'),
            (       'Veränderung',                 'T€')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1     object
31. Dezember 2020   T€                    float64
                    %                     float64
31. Dezember 2019   T€                    float64
                    %                     float64
Veränderung         T€                    float64
dtype: object
Index(['Investitionen (netto)', '2020  T€', '2019  T€', 'Veränderung  T€'], dtype='object')
Investitionen (netto)     object
2020  T€                 float64
2019  T€                 float64
Veränderung  T€          float64
dtype: object
Index(['Unnamed: 0', '€', '31.12.2019  in T €'], dtype='object')
Unnamed: 0            object
€                     object
31.12.2019  in T €    object
dtype: object
Index(['Unnamed: 0', '€', '€.1', '31.12.2019  in T €'], dtype='object')
Unnamed: 0             object
€                      object
€.1                    object
31.12.2019  in T €    float64
dtype: object
Index([0, 1], dtype='int64')
0    object
1    object
dtype: object
Index(['Beteiligung', 'Anteil', 'Eigenkapital der Beteiligungsgesellschaft',
       'Eigenkapital der Beteiligungsgesellschaft.1',
       'Jahresergebnis der Beteiligungsgesellschaft',
       'Jahresergebnis der Beteiligungsgesellschaft.1'],
      dtype='object')
Beteiligung                                      object
Anteil                                           object
Eigenkapital der Beteiligungsgesellschaft        object
Eigenkapital der Beteiligungsgesellschaft.1      object
Jahresergebnis der Beteiligungsgesellschaft      object
Jahresergebnis der Beteiligungsgesellschaft.1    object
dtype: object
Index(['Beteiligung', 'Anteil', 'Eigenkapital der Beteiligungsgesellschaft',
       'Eigenkapital der Beteiligungsgesellschaft.1',
       'Jahresergebnis der Beteiligungsgesellschaft',
       'Jahresergebnis der Beteiligungsgesellschaft.1'],
      dtype='object')
Beteiligung                                      object
Anteil                                           object
Eigenkapital der Beteiligungsgesellschaft        object
Eigenkapital der Beteiligungsgesellschaft.1      object
Jahresergebnis der Beteiligungsgesellschaft      object
Jahresergebnis der Beteiligungsgesellschaft.1    object
dtype: object
Index(['Unnamed: 0', '2020', '2019'], dtype='object')
Unnamed: 0    object
2020          object
2019          object
dtype: object
MultiIndex([(          'Unnamed: 0_level_0',        'Unnamed: 0_level_1'),
            (          'Unnamed: 1_level_0',             'Gesamt  in T€'),
            ('davon mit einer Restlaufzeit',      'bis zu 1 Jahr  in T€'),
            ('davon mit einer Restlaufzeit',    'mehr als 1 Jahr  in T€'),
            ('davon mit einer Restlaufzeit', 'davon über 5 Jahre  in T€')],
           )
Unnamed: 0_level_0            Unnamed: 0_level_1            object
Unnamed: 1_level_0            Gesamt  in T€                float64
davon mit einer Restlaufzeit  bis zu 1 Jahr  in T€         float64
                              mehr als 1 Jahr  in T€       float64
                              davon über 5 Jahre  in T€    float64
dtype: object
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                  '€'),
            (              '2019',                  '€'),
            (       'Veränderung',                  '€'),
            (       'Veränderung',                  '%')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1    object
2020                €                     object
2019                €                     object
Veränderung         €                     object
                    %                      int64
dtype: object
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                  '€'),
            (              '2019',                  '€'),
            (       'Veränderung',                  '€'),
            (       'Veränderung',                  '%')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1    object
2020                €                     object
2019                €                     object
Veränderung         €                     object
                    %                      int64
dtype: object
Index(['Unnamed: 0', '2020  T€', '2019  T€'], dtype='object')
Unnamed: 0    object
2020  T€       int64
2019  T€       int64
dtype: object
MultiIndex([(                  'Unnamed: 0_level_0',     'Unnamed: 0_level_1'),
            ('Anschaffungs- und Herstellungskosten', 'Stand am 01.01.2020  €'),
            ('Anschaffungs- und Herstellungskosten',              'Zugang  €'),
            ('Anschaffungs- und Herstellungskosten',              'Abgang  €'),
            ('Anschaffungs- und Herstellungskosten',           'Umbuchung  €'),
            ('Anschaffungs- und Herstellungskosten', 'Stand am 31.12.2020  €')],
           )
Unnamed: 0_level_0                    Unnamed: 0_level_1        object
Anschaffungs- und Herstellungskosten  Stand am 01.01.2020  €    object
                                      Zugang  €                 object
                                      Abgang  €                 object
                                      Umbuchung  €              object
                                      Stand am 31.12.2020  €    object
dtype: object
MultiIndex([('Unnamed: 0_level_0',     'Unnamed: 0_level_1'),
            (    'Abschreibungen', 'Stand am 01.01.2020  €'),
            (    'Abschreibungen',              'Zugang  €'),
            (    'Abschreibungen',        'außerplanm. AfA'),
            (    'Abschreibungen',              'Abgang  €'),
            (    'Abschreibungen',           'Umbuchung  €'),
            (    'Abschreibungen', 'Stand am 31.12.2020  €')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1         object
Abschreibungen      Stand am 01.01.2020  €     object
                    Zugang  €                  object
                    außerplanm. AfA           float64
                    Abgang  €                  object
                    Umbuchung  €              float64
                    Stand am 31.12.2020  €     object
dtype: object
MultiIndex([('Unnamed: 0_level_0',     'Unnamed: 0_level_1'),
            (     'Restbuchwerte', 'Stand am 31.12.2020  €'),
            (     'Restbuchwerte', 'Stand am 31.12.2019  €')],
           )
Unnamed: 0_level_0  Unnamed: 0_level_1        object
Restbuchwerte       Stand am 31.12.2020  €    object
                    Stand am 31.12.2019  €    object
dtype: object
Index(['Unnamed: 0', 'Elektrizitätsverteilung', '31.12.2019  in T €',
       'Gasverteilung', '31.12.2019  in T €.1'],
      dtype='object')
Unnamed: 0                 object
Elektrizitätsverteilung    object
31.12.2019  in T €         object
Gasverteilung              object
31.12.2019  in T €.1       object
dtype: object
Index(['Unnamed: 0', '€', '31.12.2019  in T €'], dtype='object')
Unnamed: 0            object
€                     object
31.12.2019  in T €    object
dtype: object
Index(['Unnamed: 0', 'Elektrizitätsverteilung  €', '31.12.2019  in T €',
       'Gasverteilung  €', '31.12.2019  in T €.1'],
      dtype='object')
Unnamed: 0                     object
Elektrizitätsverteilung  €     object
31.12.2019  in T €            float64
Gasverteilung  €               object
31.12.2019  in T €.1          float64
dtype: object
Index(['Unnamed: 0', '€', 'Vorjahr  in T €'], dtype='object')
Unnamed: 0          object
€                   object
Vorjahr  in T €    float64
dtype: object
MultiIndex([('Verbindlichkeitenspiegel 2020 Elektrizitätsverteilung', ...),
            (                         'davon mit einer Restlaufzeit', ...),
            (                         'davon mit einer Restlaufzeit', ...),
            (                         'davon mit einer Restlaufzeit', ...),
            (                         'davon mit einer Restlaufzeit', ...)],
           )
Verbindlichkeitenspiegel 2020 Elektrizitätsverteilung  Unnamed: 0_level_1          object
davon mit einer Restlaufzeit                           Gesamt  in T€              float64
                                                       bis zu 1 Jahr  in T€       float64
                                                       über 1 Jahr  in T€         float64
                                                       mehr als 5 Jahre  in T€    float64
dtype: object
MultiIndex([('Verbindlichkeitenspiegel 2020 Gasverteilung', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...)],
           )
Verbindlichkeitenspiegel 2020 Gasverteilung  Unnamed: 0_level_1          object
davon mit einer Restlaufzeit                 Gesamt  in T€              float64
                                             bis zu 1 Jahr  in T€       float64
                                             über 1 Jahr  in T€         float64
                                             mehr als 5 Jahre  in T€    float64
dtype: object
MultiIndex([('Verbindlichkeitenspiegel 2020 Intelligenter', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...)],
           )
Verbindlichkeitenspiegel 2020 Intelligenter  Messstellenbetrieb          object
davon mit einer Restlaufzeit                 Gesamt  in T€              float64
                                             bis zu 1 Jahr  in T€       float64
                                             über 1 Jahr  in T€         float64
                                             mehr als 5 Jahre  in T€    float64
dtype: object
In [81]:
current_table = tables[1]
current_table.head()
Out[81]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead tr th { text-align: left; } </style>
Unnamed: 0_level_0 2020 2019 Veränderungen
Unnamed: 0_level_1 T€ % T€ % T€ %
0 Umsatzerlöse 47.459 978 45.575 970 1.884 41
1 Aktivierte Eigenleistungen 380.000 8 400.000 9 -20.000 -50
2 Sonstige betriebliche Erträge 687.000 14 991.000 21 -304.000 -307
3 Betriebliche Erträge 48.526 1000 46.966 1000 1.560 33
4 Materialaufwand 34.007 701 32.647 695 1.360 42
In [82]:
import re


def cleanse_string(value: str) -> str:
    if value is not None and isinstance(value, str):
        return re.sub(r"(.+\.).", "", value)
    return None
In [83]:
for index, row in current_table.iterrows():
    current_table.iloc[index][0] = cleanse_string(row[0])
current_table.head()
C:\Users\trist\AppData\Local\Temp\ipykernel_15672\152097142.py:2: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  current_table.iloc[index][0] = cleanse_string(row[0])
C:\Users\trist\AppData\Local\Temp\ipykernel_15672\152097142.py:2: FutureWarning: Series.__setitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To set a value by position, use `ser.iloc[pos] = value`
  current_table.iloc[index][0] = cleanse_string(row[0])
Out[83]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead tr th { text-align: left; } </style>
Unnamed: 0_level_0 2020 2019 Veränderungen
Unnamed: 0_level_1 T€ % T€ % T€ %
0 Umsatzerlöse 47.459 978 45.575 970 1.884 41
1 Aktivierte Eigenleistungen 380.000 8 400.000 9 -20.000 -50
2 Sonstige betriebliche Erträge 687.000 14 991.000 21 -304.000 -307
3 Betriebliche Erträge 48.526 1000 46.966 1000 1.560 33
4 Materialaufwand 34.007 701 32.647 695 1.360 42
In [84]:
def parse_string_to_float(value) -> float:
    try:
        if value is None:
            return None
        if isinstance(value, float):
            return value
        return float(value.replace(".", "").replace(",", "."))
    except Exception as e:
        return None


def apply_factor(value, factor: float):
    transformed_value = parse_string_to_float(value)
    if transformed_value is None or isinstance(transformed_value, str):
        return None
    result = transformed_value * factor
    # print(result)
    return result
In [85]:
converter = {
    "Mio€": 1 * 10**6,
    "Mio": 1 * 10**6,
    "T€": 1 * 10**3,
    "TEUR": 1 * 10**3,
    "EUR": 1,
    "€": 1,
}

for column in current_table.columns:
    if isinstance(column, tuple):
        for c in column:
            for x, factor in converter.items():
                if x in c:
                    current_table[column] = current_table[column].apply(
                        lambda x: apply_factor(x, factor)
                    )
                    next
    else:
        for x, factor in converter.items():
            parts = column.split(" ")
            for y in parts:
                if re.match(x, y):
                    current_table[column] = current_table[column].apply(
                        lambda x: apply_factor(x, factor)
                    )
                    current_table.rename({column: parts[0]}, inplace=True, axis=1)
                    next
                # print(current_table[column])
current_table.dropna(axis=0, how="all", inplace=True)
current_table.dropna(axis=1, how="all", inplace=True)
current_table.head()
Out[85]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead tr th { text-align: left; } </style>
Unnamed: 0_level_0 2020 2019 Veränderungen
Unnamed: 0_level_1 T€ % T€ % T€ %
0 Umsatzerlöse 47459.0 978 45575.0 970 1884.0 41
1 Aktivierte Eigenleistungen 380000.0 8 400000.0 9 -20000.0 -50
2 Sonstige betriebliche Erträge 687000.0 14 991000.0 21 -304000.0 -307
3 Betriebliche Erträge 48526.0 1000 46966.0 1000 1560.0 33
4 Materialaufwand 34007.0 701 32647.0 695 1360.0 42
In [86]:
current_table.dtypes
Out[86]:
Unnamed: 0_level_0  Unnamed: 0_level_1     object
2020                T€                    float64
                    %                       int64
2019                T€                    float64
                    %                       int64
Veränderungen       T€                    float64
                    %                       int64
dtype: object
In [87]:
# Remove columns hosting non-numerics; excl. first column hosting keys
columns_to_prune = []
for column_index, column_type in enumerate(current_table.dtypes[1:]):
    if column_type in ["object", "str"]:
        columns_to_prune.append(column_index + 1)

current_table = current_table.drop(
    current_table.columns[columns_to_prune], axis="columns"
)
In [88]:
# Prune rows where first columns is None
import numpy as np

current_table = current_table.replace(to_replace="None", value=np.nan).dropna()
current_table
Out[88]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead tr th { text-align: left; } </style>
Unnamed: 0_level_0 2020 2019 Veränderungen
Unnamed: 0_level_1 T€ % T€ % T€ %
0 Umsatzerlöse 47459.0 978 45575.0 970 1884.0 41
1 Aktivierte Eigenleistungen 380000.0 8 400000.0 9 -20000.0 -50
2 Sonstige betriebliche Erträge 687000.0 14 991000.0 21 -304000.0 -307
3 Betriebliche Erträge 48526.0 1000 46966.0 1000 1560.0 33
4 Materialaufwand 34007.0 701 32647.0 695 1360.0 42
5 Personalaufwand 6258.0 129 6222.0 132 36000.0 6
6 Abschreibungen 2239.0 46 2273.0 48 -34000.0 -15
7 Konzessionsabgabe 1331.0 27 1302.0 28 29000.0 22
8 Übrige sonstige betriebliche Aufwendungen 2100.0 43 2066.0 44 34000.0 16
9 Betriebliche Aufwendungen 45935.0 947 44510.0 948 1425.0 32
10 Ergebnis der betrieblichen Tätigkeit 2591.0 53 2456.0 52 135000.0 55
11 Finanzergebnis (Ertrags-/Aufwandsaldo) -13000.0 0 -99000.0 -2 86000.0 -869
12 sonstige Steuern 147000.0 3 164000.0 3 -17000.0 -104
13 Neutraler Bereich 134000.0 3 65000.0 1 86000.0 1062
14 Jahresüberschuss vor Ertragsteuern 2457.0 51 2391.0 51 66000.0 28
15 Ertragsteuern 796000.0 16 792000.0 17 4000.0 5
16 Jahresüberschuss 1661.0 34 1599.0 34 62000.0 39
In [89]:
kpis = {}
for _index, row in current_table.iterrows():
    kpis[row[0]] = row[1]
kpis
C:\Users\trist\AppData\Local\Temp\ipykernel_15672\340569398.py:3: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  kpis[row[0]] = row[1]
Out[89]:
{'Umsatzerlöse': 47459.0,
 'Aktivierte Eigenleistungen': 380000.0,
 'Sonstige betriebliche Erträge': 687000.0,
 'Betriebliche Erträge': 48526.0,
 'Materialaufwand': 34007.0,
 'Personalaufwand': 6258.0,
 'Abschreibungen': 2239.0,
 'Konzessionsabgabe': 1331.0,
 'Übrige sonstige betriebliche Aufwendungen': 2100.0,
 'Betriebliche Aufwendungen': 45935.0,
 'Ergebnis der betrieblichen Tätigkeit': 2591.0,
 'Finanzergebnis (Ertrags-/Aufwandsaldo)': -13000.0,
 'sonstige Steuern': 147000.0,
 'Neutraler Bereich': 134000.0,
 'Jahresüberschuss vor Ertragsteuern': 2457.0,
 'Ertragsteuern': 796000.0,
 'Jahresüberschuss': 1661.0}
In [90]:
import re


def get_bilanz(report: str) -> any:
    result = {}
    soup = BeautifulSoup(report, features="html.parser")
    for pos in ["Aktiva", "Passiva"]:
        tag = soup.find("b", string=re.compile(pos))
        if tag:
            pos_results = pd.read_html(
                StringIO(str(tag.findNext("table", {"class": "std_table"})))
            )[0]
            result[pos] = pos_results
        else:
            result[pos] = pd.DataFrame([])
    return result
In [91]:
bilanz = get_bilanz(sample_report)
bilanz["Passiva"].head()
Out[91]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; } </style>
Investitionen (netto) 2020 T€ 2019 T€ Veränderung T€
0 Stromversorgung 1.372 1.553 -181.000
1 Gasversorgung 713.000 707.000 6.000
2 sonstige Aktivitäten 661.000 2.605 -1.944
3 Insgesamt 2.746 4.865 -2.119
In [92]:
bilanz["Aktiva"].head()
Out[92]:
<style scoped=""> .dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead tr th { text-align: left; } </style>
Unnamed: 0_level_0 31. Dezember 2020 31. Dezember 2019 Veränderung
Unnamed: 0_level_1 T€ % T€ % T€
0 Anlagevermögen NaN NaN NaN NaN NaN
1 Sachanlagen 28.919 689.0 28.812 689.0 107.000
2 Finanzanlagen 2.667 64.0 4.189 100.0 -1.522
3 NaN 31.586 753.0 33.001 789.0 -1.415
4 Umlaufvermögen NaN NaN NaN NaN NaN
In [93]:
from IPython.display import display, HTML

# Assuming that dataframes df1 and df2 are already defined:
display(HTML(bilanz["Passiva"].to_html()))
Investitionen (netto) 2020 T€ 2019 T€ Veränderung T€
0 Stromversorgung 1.372 1.553 -181.000
1 Gasversorgung 713.000 707.000 6.000
2 sonstige Aktivitäten 661.000 2.605 -1.944
3 Insgesamt 2.746 4.865 -2.119
In [94]:
def get_tables(raw_report: str) -> list:
    soup = BeautifulSoup(raw_report, features="html.parser")
    tables = soup.find_all("table", {"class": "std_table"})
    dfs = []
    for table in tables:
        for df in pd.read_html(StringIO(str(table))):
            dfs.append(df)
    return dfs


for df in get_tables(sample_report):
    print(df.columns)

tables = get_tables(sample_report)
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                 'T€'),
            (              '2019',                 'T€'),
            (       'Veränderung',                 'T€'),
            (       'Veränderung',                  '%')],
           )
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                 'T€'),
            (              '2020',                  '%'),
            (              '2019',                 'T€'),
            (              '2019',                  '%'),
            (     'Veränderungen',                 'T€'),
            (     'Veränderungen',                  '%')],
           )
MultiIndex([('Unnamed: 0_level_0', 'gerundet'),
            (              '2020',       'T€'),
            (              '2019',       'T€'),
            (       'Veränderung',       'T€'),
            (       'Veränderung',        '%')],
           )
MultiIndex([('Unnamed: 0_level_0', 'unkonsolidiert gerundet'),
            (              '2020',                      'T€'),
            (              '2019',                      'T€'),
            (       'Veränderung',                      'T€'),
            (       'Veränderung',                       '%')],
           )
MultiIndex([('Jahresüberschuss/Jahresfehlbetrag nach Betriebszweigen', ...),
            (                                                  '2020', ...),
            (                                                  '2019', ...),
            (                                           'Veränderung', ...),
            (                                           'Veränderung', ...)],
           )
Index(['Unnamed: 0', '2020  T€', '2019  T€'], dtype='object')
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            ( '31. Dezember 2020',                 'T€'),
            ( '31. Dezember 2020',                  '%'),
            ( '31. Dezember 2019',                 'T€'),
            ( '31. Dezember 2019',                  '%'),
            (       'Veränderung',                 'T€')],
           )
Index(['Investitionen (netto)', '2020  T€', '2019  T€', 'Veränderung  T€'], dtype='object')
Index(['Unnamed: 0', '€', '31.12.2019  in T €'], dtype='object')
Index(['Unnamed: 0', '€', '€.1', '31.12.2019  in T €'], dtype='object')
Index([0, 1], dtype='int64')
Index(['Beteiligung', 'Anteil', 'Eigenkapital der Beteiligungsgesellschaft',
       'Eigenkapital der Beteiligungsgesellschaft.1',
       'Jahresergebnis der Beteiligungsgesellschaft',
       'Jahresergebnis der Beteiligungsgesellschaft.1'],
      dtype='object')
Index(['Beteiligung', 'Anteil', 'Eigenkapital der Beteiligungsgesellschaft',
       'Eigenkapital der Beteiligungsgesellschaft.1',
       'Jahresergebnis der Beteiligungsgesellschaft',
       'Jahresergebnis der Beteiligungsgesellschaft.1'],
      dtype='object')
Index(['Unnamed: 0', '2020', '2019'], dtype='object')
MultiIndex([(          'Unnamed: 0_level_0',        'Unnamed: 0_level_1'),
            (          'Unnamed: 1_level_0',             'Gesamt  in T€'),
            ('davon mit einer Restlaufzeit',      'bis zu 1 Jahr  in T€'),
            ('davon mit einer Restlaufzeit',    'mehr als 1 Jahr  in T€'),
            ('davon mit einer Restlaufzeit', 'davon über 5 Jahre  in T€')],
           )
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                  '€'),
            (              '2019',                  '€'),
            (       'Veränderung',                  '€'),
            (       'Veränderung',                  '%')],
           )
MultiIndex([('Unnamed: 0_level_0', 'Unnamed: 0_level_1'),
            (              '2020',                  '€'),
            (              '2019',                  '€'),
            (       'Veränderung',                  '€'),
            (       'Veränderung',                  '%')],
           )
Index(['Unnamed: 0', '2020  T€', '2019  T€'], dtype='object')
MultiIndex([(                  'Unnamed: 0_level_0',     'Unnamed: 0_level_1'),
            ('Anschaffungs- und Herstellungskosten', 'Stand am 01.01.2020  €'),
            ('Anschaffungs- und Herstellungskosten',              'Zugang  €'),
            ('Anschaffungs- und Herstellungskosten',              'Abgang  €'),
            ('Anschaffungs- und Herstellungskosten',           'Umbuchung  €'),
            ('Anschaffungs- und Herstellungskosten', 'Stand am 31.12.2020  €')],
           )
MultiIndex([('Unnamed: 0_level_0',     'Unnamed: 0_level_1'),
            (    'Abschreibungen', 'Stand am 01.01.2020  €'),
            (    'Abschreibungen',              'Zugang  €'),
            (    'Abschreibungen',        'außerplanm. AfA'),
            (    'Abschreibungen',              'Abgang  €'),
            (    'Abschreibungen',           'Umbuchung  €'),
            (    'Abschreibungen', 'Stand am 31.12.2020  €')],
           )
MultiIndex([('Unnamed: 0_level_0',     'Unnamed: 0_level_1'),
            (     'Restbuchwerte', 'Stand am 31.12.2020  €'),
            (     'Restbuchwerte', 'Stand am 31.12.2019  €')],
           )
Index(['Unnamed: 0', 'Elektrizitätsverteilung', '31.12.2019  in T €',
       'Gasverteilung', '31.12.2019  in T €.1'],
      dtype='object')
Index(['Unnamed: 0', '€', '31.12.2019  in T €'], dtype='object')
Index(['Unnamed: 0', 'Elektrizitätsverteilung  €', '31.12.2019  in T €',
       'Gasverteilung  €', '31.12.2019  in T €.1'],
      dtype='object')
Index(['Unnamed: 0', '€', 'Vorjahr  in T €'], dtype='object')
MultiIndex([('Verbindlichkeitenspiegel 2020 Elektrizitätsverteilung', ...),
            (                         'davon mit einer Restlaufzeit', ...),
            (                         'davon mit einer Restlaufzeit', ...),
            (                         'davon mit einer Restlaufzeit', ...),
            (                         'davon mit einer Restlaufzeit', ...)],
           )
MultiIndex([('Verbindlichkeitenspiegel 2020 Gasverteilung', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...)],
           )
MultiIndex([('Verbindlichkeitenspiegel 2020 Intelligenter', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...),
            (               'davon mit einer Restlaufzeit', ...)],
           )