UnicodeEncodeError

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
kaaniboy68
User
Beiträge: 3
Registriert: Sonntag 15. September 2019, 16:22

Hallo,

ich versuche zur Zeit eine HTML Tabelle in eine .csv zu schreiben.

Mein bisheriger Code:

Code: Alles auswählen

from bs4 import BeautifulSoup
import csv

html = open("/Users/kaanekici/Documents/Programmiern/GymHVertretungen/GymHVertretungenHTML.html").read()
soup = BeautifulSoup(html, features='lxml')
table = soup.find(class_="TabelleVertretungen")

output_rows = []
for table_row in table.findAll('tr'):
    columns = table_row.findAll('td')
    # for xtext in columns:
    #     print(xtext.get_text())
    output_row = []
    for column in columns:
        output_row.append(column.text)
    output_rows.append(output_row)

with open('output.csv', 'wb') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerows(output_rows)
Nach ausführen bekomme ich die Fehlermeldung: "UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-6: ordinal not in range(128)"

Ich weiß nicht, wie ich den Fehler gefixt bekomme; kann mir jemand helfen?
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Immer wenn man open verwendet, sollte man auch ein Encoding angeben. Das sollte dein Problem lösen.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kaaniboy68: Das mit dem Encoding gilt für Textdateien, also so wie das Programm jetzt ist, auch für den HTML-Quelltext der eingelesen wird. Alternativ kann man den auch als Binärdaten einlesen und an `BeautifulSoup` verfüttern.

Auch beim einlesen sollte man die Datei sicher wieder schliessen und sich nicht auf die autmatische Speicherbereinigung verlassen. Also ``with`` auch dort verwenden, oder `pathlib.Path` was eine Methode hat die sich um öffnen, einlesen, schliessen kümmert.

Beim öffnen von Dateien für das `csv`-Modul ist es wichtig ``newline=""`` als Argument anzugeben, sonst kann man damit kaputte CSV-Dateien erzeugen.

Die Schriebweise von `findAll()` entspricht nicht den Namenskonventionen, darum sollte man diese Methode nicht mehr verwenden, sondern `find_all()`. Was übrigens den gleichen Effekt hat wie das `Tag`-Objekt direkt aufzurufen.

Die innere ``for``-Schleife lässt sich leicht als „list comprehension“ ausdrücken. Und wenn man das gemacht hat, sieht man, dass man das dann auch mit der äusseren ``for``-Schleife machen kann.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3
import csv
from pathlib import Path

from bs4 import BeautifulSoup


HTML_FILE_PATH = Path(
    "/Users/kaanekici/Documents/Programmiern/GymHVertretungen/GymHVertretungenHTML.html"
)


def main():
    soup = BeautifulSoup(HTML_FILE_PATH.read_bytes(), "lxml")
    output_rows = [
        [column.text for column in table_row("td")]
        for table_row in soup.find(class_="TabelleVertretungen")("tr")
    ]
    with open("output.csv", "w", newline="", encoding="utf-8") as csv_file:
        csv.writer(csv_file).writerows(output_rows)


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten