Webseite auslesen: Umlaute werden falsch codiert…

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
Rotmilan
User
Beiträge: 32
Registriert: Mittwoch 30. Dezember 2020, 21:59
Wohnort: Nordbayern

Hallo,
mir fehlt gerade der Ansatzpunkt, weil ich auch keinen wirklichen Begriff habe um das Problem zu beschreiben.
Ich lese mit BeautifulSoup html-Code ein
soup = BeautifulSoup(string_aus_datei, 'html.parser')
Suche mir dann den per CSS den Teil, den ich haben möchte
content1 = soup.select(css_ident)
Bekomme aber dann Umlaute nicht richtig übergeben.

Konkret:
In der Webseite steht „...Hück...“ und in der
Ausgabe von content1 bekomme ich „...H\xc3\xbcck...“

Wo muss ich da ansetzen? liegt das am parser, oder fehlt mir noch ein attribut? Ich habe keine Ahnung...
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sind UTF-8-encodierte Daten. Wie auch immer du den String einliest, da ist dein Problem. Da muss das encoding angegeben werden, open(filename, ..., encoding='utf-8') Zb
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wie wird die Datei denn eingelesen? Ich würde es ja erst einmal als Binärdatei versuchen, denn HTML kann in verschiedenen Kodierungen vorliegen und wenn man Binärdaten an den Parser übergibt, dann ist der dafür zuständig die Kodierung zu wählen. Die steht ja in der Regel dann in den Metadaten im HTML-<head>.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Rotmilan
User
Beiträge: 32
Registriert: Mittwoch 30. Dezember 2020, 21:59
Wohnort: Nordbayern

Das ist der originalcode der Funktion, die die Suppe erzeugt:
def extract_soup_from_datei(filename):
datei = open(f'{PATH_WEBSITE_FILES}{filename}', 'rb')
filecontent = datei.read()
soup = BeautifulSoup(str(filecontent), 'html.parser')
datei.close()
return soup
ich lese also schon binär aus

habe den code wie folgt abgeändert:
def extract_soup_from_datei(filename):
datei = open(f'{PATH_WEBSITE_FILES}{filename}', 'r', encoding='utf-8')
filecontent = datei.read()
soup = BeautifulSoup(str(filecontent), 'html.parser')
datei.close()
return soup
... und er funktioniert! :D

1000 Dank an __deets__ !!! :D
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schoen das es funktioniert. Die Verwendung von format-Strings fuer die Pfaderzeugung ist aber ein no-no. Dazu benutzt man pathlib.Path, zB so

Code: Alles auswählen

PATH_WEBSITE_FILES = pathlib.Path("/ein/toller/verzeichnis/pfad")

def extract_soup_from_file(filename) # warum bei dir denglish?
     filecontent = (PATH_WEBSITE_FILES / filename).read_text(encoding="UTF-8")
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Rotmilan: Zusätzlich zu der Anmerkung von __deets__: `read()` bei einer Datei die im Textmodus geöffnet wurde, liefert eine Zeichenkette. Es macht keinen Sinn die in eine Zeichenkette umzuwandeln, denn das ist bereits eine. Die wird durch das `str()` nicht irgendwie “noch zeichenkettiger“.

Wenn man `open()` verwendet, dann am besten mit der ``with``-Anweisung. Aber die Verwendung von `Path`-Objekten wie __deets__ das zeigt, ist in diesem Fall natürlich noch besser. Da kann man am Ende die gesamte Funktion in einem einzigen Ausdruck unterbringen.

Code: Alles auswählen

def load_soup(filename):
    return BeautifulSoup(
        (WEBSITE_FILES_PATH / filename).read_text(encoding="UTF-8"),
        "html.parser",
    )
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Rotmilan
User
Beiträge: 32
Registriert: Mittwoch 30. Dezember 2020, 21:59
Wohnort: Nordbayern

Danke euch! Nu hat es mir durch die andere Codierung allerdings was anderes zerhaut, aber das ist mein Problem ;-)

Nur noch kurz die Frage: Warum sind Formatstrings da nicht erlaub an der Stelle? Ich begreife die Sachen immer gern, dann kann man sie besser anwenden ;-)

Bzgl. denglish: manchmal merke ich es gar nicht :D
und manchmal mache ich es absichtlich, weil man sich nicht mit geschützen wörtern in die Quere kommt, und für anderes fällt mir mal keine passende übersetzung ein - im falle von datei wars aber unabsichtlich ;-)
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sie sind erlaubt, sie sind nur sauschlecht. Dein Code zB verlaesst sich darauf, dass PATH_WEBSITE_FILES mit einem "/" endet. Wehe wenn nicht! Dann baust du einen falschen Pfad zusammen. Und wenn du stattdessen einen "/" in den Formatstring packst, und PATH_WEBSITE_FILES *hat* einen "/" am Ende, dann steht da "foo//bar", und macht dir Probleme an anderer Stelle, zb wenn du den wieder mit split zerlegst. Weswegen man auch das nicht tut.

Pfade haben bestimmte Semantik, das sind nicht nur Strings. Und darum benutzt man keine Stringmanipulation, um mit ihnen zu arbeiten. Wenigstens die os.path Funktionen sollte man verwenden, aber seit Einfuehrung der pathlib ist es wesentlich angenehmer und leistungsfaehiger damit zu arbeiten.
Rotmilan
User
Beiträge: 32
Registriert: Mittwoch 30. Dezember 2020, 21:59
Wohnort: Nordbayern

ok, danke, schau ich mir mal an - wobei das nicht das große problem ist mit dem "/" am ende vom pfad, indem fall, weil es eine konstante ist, die ich festlege
__deets__
User
Beiträge: 14528
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dann. Wenn du niemals Fehler machst, und alle, die deinen Code jemals benutzen werden, ebenfalls niemals Fehler machen, dann musst du dir selbstverstaendlich nichts angewoehen, das so kompliziert und schwer zu benutzen ist wie pfad / "name", und kannst stattdessen weiterhin so arbeiten, wie bisher.
Rotmilan
User
Beiträge: 32
Registriert: Mittwoch 30. Dezember 2020, 21:59
Wohnort: Nordbayern

Lieber __deets__,
ich mache andauernd Fehler, :roll: und bin ganz froh, dass Python die Fehler immer so schön anzeigt. Natürlich bin ich dankbar für solche Hinweise und weiß das sehr zu schätzen, sonst hätte das einfach ignoriert und nicht mehr nachgefragt. Im Moment stecke ich einfach schon sehr viel Zeit da rein die Sprache zu lernen, da bin ich froh wenn was erst mal so funktioniert (gerade wenn es schon geschrieben ist). Ich habe deinen Hinweis aber durchaus im Hinterkopf und werde mir das sicher auch mal anschauen und ändern. Deshalb noch mal vielen Dank :wink:
... und schönes Wochenende noch!
Antworten