Börse und Übersicht - Richtige Kodierung?

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
blck
User
Beiträge: 11
Registriert: Sonntag 17. Juli 2011, 00:37

Ersteinmal ein herzliches Hallo an alle Boardmitglieder! Mein Name ist Blck ich bin hobbymäßiger Programmierer und habe Probleme (und das nicht nur beim Programmieren :mrgreen: )

Nun zu meinem aktuellen Problem:
Ich sitze derzeit an so etwas wie einem Newscrawler. Dabei durchsuche ich hauptsächlich News-Webseiten und gebe deren Inhalt wieder. Dazu nutze ich BeautifulSoup, was ja Ergebnisse in UTF-8-Kodierung wieder gibt. So weit kein Problem, lässt sich automatisch in das richtige Format umwandeln.
Im Internet habe ich gelesen, dass es sich der interoperabilität wegen lohnt, dass Skript gleich am Anfang als UTF-8-kodiert zu markieren, sprich

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
.

Nun habe ich mir einen Dictonary erstellt, in dem sich auch Worte mit Umlauten befinden, beispielsweise "Übersicht". Nach dem Kompillieren wird daraus aber "Ãœbersicht" und aus "Börse" wird "Börse". Ich hab schon die verschiedensten Decodierungs- und Encodierungsvarianten versucht. Oftmals bekomme ich aber diesen ascii-Fehler, dass ein bestimmtes Zeichen nicht umgewandelt werden kann. Habt ihr eine Idee was ich da tun kann?

MfG Blck

Hier noch der Code-Schnipsel:

Code: Alles auswählen

        ntv_cat = {"Übersicht":"http://www.n-tv.de/rss", "Politik":"http://www.n-tv.de/politik/rss", "Wirtschaft":"http://www.n-tv.de/wirtschaft/rss",
                   "Börse":"http://www.n-tv.de/boerse/rss", "Sport":"http://www.n-tv.de/sport/rss", "Panorama":"http://www.n-tv.de/panorama/rss",
                   "Unterhaltung":"http://www.n-tv.de/unterhaltung/rss", "Auto":"http://www.n-tv.de/auto/rss", "Technik":"http://www.n-tv.de/technik/rss",
                   "Wissen":"http://www.n-tv.de/wissen/rss", "Ratgeber":"http://www.n-tv.de/ratgeber/rss", "Reise":"http://www.n-tv.de/reise/rss"}
        ntv_cat_sorted = {}
        ntv_cat_sorted = sorted(ntv_cat.items())
        
        i = 0
        for cat in ntv_cat_sorted:
                kategorie = str(i)
                print kategorie + ") " + cat[0]
                i=i+1
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Das riecht irgendwie nach kaputtem Windows-Terminal. Würde mich nicht wundern, wenn die nicht mal UTF-8 können. Vielleicht hilft es was, die Strings mit "u" zu Prefixen, sodass zur "Kompilier"zeit daraus Unicode-Strings werden?

Code: Alles auswählen

{u"Gedödel":  ...}
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Ach übrigens: Statt `i` manuell hochzuzählen kannst du einfach `enumerate` verwenden:

Code: Alles auswählen

for i, cat in enumerate(ntv_cat_sorted)
Und statt auf Key und Value der Dictionary-Items mit `[0...]` zuzugreifen könnte man die auch automagisch entpacken lassen:

Code: Alles auswählen

for name, url in ntv_cat_sorted
und kombiniert mit dem `i`:

Code: Alles auswählen

for i, (name, url) in enumerate(ntv_cat_sorted)
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

blck hat geschrieben:Im Internet habe ich gelesen, dass es sich der interoperabilität wegen lohnt, dass Skript gleich am Anfang als UTF-8-kodiert zu markieren, sprich

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
.
Zusätzlich würde ich dann auch konsequent nur mit Unicode-Strings arbeiten, wie es unter Python 3 ebenfalls gemacht wird. Am einfachsten erreichst du das mit folgendem Import:

Code: Alles auswählen

from __future__ import unicode_literals
Das sollte dein Problem lösen.
blck
User
Beiträge: 11
Registriert: Sonntag 17. Juli 2011, 00:37

Hallo,
danke für eure Antworten und Verbesserungsvorschläge. Werde es bei Zeiten mal einfließen lassen und dann nochmal eine Rückmeldung geben.

MfG Blck
blck
User
Beiträge: 11
Registriert: Sonntag 17. Juli 2011, 00:37

Hallo,
muss leider nochmal nachfragen. Ich hab das Programm jetzt etwas umgeschrieben. Nun steht eine Datenbank hinter. Hab jetzt aber ein weiteres Problem mit den Sonderzeichen. Diesmal handelt es sich um eine Webseite die in UTF-8 kodiert ist (jedenfalls nach Quelltext) und da Beautifulsoup auch mit utf-8 arbeitet, sollte das kein Problem sein. Je nach Variante kriege ich aber folgende Fehlermeldungen(In der ersten Variante funktioniert es, nur werden da leider die Sonderzeichen falsch dargestellt.) Oben in der Datei steht jeweils:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
- __future__ kann ich leider nicht nutzen (mobile Anwendung)
1)

Code: Alles auswählen

                #Nachricht des Users ermitteln
                nachricht_hilf = soup.findAll('div', { "class" : "kmsgtext" })
                #nachricht = StripTags(nachricht_hilf[i].renderContents())
                nachricht = str(nachricht_hilf[i])
                insert = (thread, entry.title, user_string , nachricht.decode('utf-8'))
                cursor.execute('INSERT INTO Meego values(?,?,?,?)', insert)
2) Ich dachte mir, da ja alles utf-8 ist, kann ich nachricht ja einfach so einfügen. Sieht dann so aus:

Code: Alles auswählen

#Nachricht des Users ermitteln
                nachricht_hilf = soup.findAll('div', { "class" : "kmsgtext" })
                #nachricht = StripTags(nachricht_hilf[i].renderContents())
                nachricht = nachricht_hilf[i]
                insert = (thread, entry.title, user_string , nachricht)
                cursor.execute('INSERT INTO Meego values(?,?,?,?)', insert)
Das gibt folgende Fehlermeldung:

Code: Alles auswählen

    cursor.execute('INSERT INTO Meego values(?,?,?,?)', insert)
InterfaceError: Error binding parameter 3 - probably unsupported type.
3) Und wenn ich versuche, die Variable nachricht in utf-8 zu dekodieren, sprich so:

Code: Alles auswählen

                #Nachricht des Users ermitteln
                nachricht_hilf = soup.findAll('div', { "class" : "kmsgtext" })
                #nachricht = StripTags(nachricht_hilf[i].renderContents())
                nachricht = nachricht_hilf[i]
                insert = (thread, entry.title, user_string , nachricht.decode('utf-8'))
                cursor.execute('INSERT INTO Meego values(?,?,?,?)', insert)

Code: Alles auswählen

    insert = (thread, entry.title, user_string , nachricht.decode('utf-8'))
TypeError: 'NoneType' object is not callable
ein ".encode('utf-8') wirft dann den ASCII-Fehler raus.
Habt ihr noch eine Idee?

MfG Blck
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Könntest du bitte für deine nächsten Posts die python Code Tags benutzen? Damit hat man dann auch Syntax-Highlighting. Zu deinem Problem: In deinen Schnippseln taucht, sofern ich das richtig lese, nirgends ein UnicodEncode/Decode-Error auf. Deshalb kann ich nicht nachvollziehen, wo dein Problem liegt. Wie wäre es denn mit einem Minimalbeispiel?

Noch mal zur Verdeutlichung: decode() wendet man auf einen Bytestring in utf-8, cp1252 etc. an, um ein Unicode String zu erhalten. encode() wendet man auf einen Unicode String an, um einen Bytestring in utf-8, cp1252 etc. zu erhalten.
BlackJack

@blck: Setz mal bei der ersten Fehlannahme an, aus der sich dann wahrscheinlich Folgefehler in Deinem Denken ergeben: BeautifulSoup arbeitet nicht mit UTF-8 sondern mit Unicode. Das ist nicht das selbe. Unicode ist eine abstrakte Idee mit einem eigenen Datentyp in Python (`unicode`) und UTF-8 ist eine konkrete Kodierung von Unicode für eine Bytekette (Datentyp `str`).
blck
User
Beiträge: 11
Registriert: Sonntag 17. Juli 2011, 00:37

BlackJack hat geschrieben:@blck: Setz mal bei der ersten Fehlannahme an, aus der sich dann wahrscheinlich Folgefehler in Deinem Denken ergeben: BeautifulSoup arbeitet nicht mit UTF-8 sondern mit Unicode. Das ist nicht das selbe. Unicode ist eine abstrakte Idee mit einem eigenen Datentyp in Python (`unicode`) und UTF-8 ist eine konkrete Kodierung von Unicode für eine Bytekette (Datentyp `str`).
Treffer! Versenkt! Das war in der Tat mein Denkfehler.

MfG Blck

P.S. Die letzten Wochen waren etwas verplant, deshalb erst jetzt die Antwort.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Auch wenn Du das jetzt kapiert hast, verweise ich noch mal auf meine Sig - das hat mir seinerzeit geholfen, das ganze zu kapieren.

Fühle mich schon als Coding-Inspektor :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten