@HoLyYy: Zum ersten Programm: `requests` wird importiert aber nicht verwendet.
`Spalten` ist ein sehr irreführender Name für ein Objekt das *eine* *Zeile* repräsentiert. Das sollte wohl eher `Zeile` oder `Datensatz` heissen, oder noch besser ein Name der beschreibt was so ein Objekt im Kontext des Programms bedeutet.
Eingerückt wird per Konvention mit vier Leerzeichen pro Ebene, nicht mit drei.
Bei dem regulären Ausdruck kann man sich das "^" am Anfang sparen, das ist bei der `match()`-Methode implizit, und das ".*" am Ende, denn *jede* Zeichenkette endet mit 0 oder mehr beliebigen Zeichen.
Sind die "." zwischen den Datumsteilen so gewollt? So ein "." steht für ein *beliebiges* Zeichen und nicht für einen Punkt! Kann auch eine weitere Ziffer sein. Wenn eine Zeile mit zehn Ziffern beginnt, dann ist das ein erfolgreicher Match mit dem Ausdruck, den Du da angegeben hast!
Das in `bezahlung` alle restlichen Teile (selbst wenn es nur einer oder keiner ist) in einer Liste gesammelt wird, die dann als *ein Wert* im CSV landen soll ist falsch. Selbst wenn man mehrere Werte in einer Zelle unterbringen möchte, würde man das nicht als Zeichenkettendarstellung einer Python-Liste machen, sondern etwas das man auch einfach wieder in eine Datenstruktur bringen kann. Also beispielsweise als JSON.
Wenn man die Textzeile aufteilt und davon per Slicing die ersten fünf Elemente nimmt, lässt sich die ``for``-Schleife durch eine „list comprehension“ ersetzen.
Was beim Speicher als CSV hier keinen Sinn macht ist das der namenlose Index als erste Spalte mitgespeichert wird. Der bringt hier absolut keinen Mehrwert.
Zwischenstand:
Code: Alles auswählen
#!/usr/bin/env python3
import re
from collections import namedtuple
import pandas as pd
import pdfplumber
Datensatz = namedtuple("Datensatz", "Datum Zeit Beleg Preis Online")
def main():
with pdfplumber.open("test.pdf") as pdf:
text = pdf.pages[0].extract_text()
#
# FIXME Really *any* character between the number groups?
#
faengt_mit_datum_an = re.compile(r"\d{2}.\d{2}.\d{4}").match
pd.DataFrame(
[
Datensatz(*line.split()[:5])
for line in text.splitlines()
if faengt_mit_datum_an(line)
]
).to_csv("ausgabe.csv", index=False)
if __name__ == "__main__":
main()
Allerdings würde ich hier schon korrigieren das Datum und Zeit in zwei Spalten stehen. Beide Spalten gehören eigentlich zusammen in eine Spalte "Zeitpunkt" oder ähnlich, und dann auch gleich in einem vernünftigen Format. Das kann man mit Pandas erledigen.
Was Du mit dem zweiten Programm bezwecken willst ist mir nicht so ganz klar. Im Grunde lässt das ja nur die Indexspalte weg, die man im ersten Programm gar nicht erst schreiben sollte. Andererseits stört die auch nicht zwangsläufig bei der Weiterverarbeitung. Die kann man dann ja immer noch ignorieren.
Wie kommst Du darauf das alles in einer Spalte stehen würde? Excel? Nimm was anderes wo man beim öffnen von CSV-Dateien angeben kann welches Trennzeichen verwendet wurde. Das hängt bei Excel nämlich von der eingestellten Sprache ab. Und AFAIK kann man das auch nicht manuell ändern wenn man eine CSV-Datei öffnet. Und die komische Unart zu versuchen alles mögliche als Datum oder Zeitangabe zu verstehen kann man Excel soweit ich weiss auch nicht abgewöhnen. Kann man mich da an ”lustige” Sachen mit Adresslisten mit eigener Spalte für Hausnummern erinnern. Aus der Hausnummer 7a wurde die Zeit 7 Uhr, weil das als "7 a.m." interpretiert wurde. Auf einem deutschen Windows mit deutschem Office wohlgemerkt. Und das war dieser Kacksoftware nicht abzugewöhnen.