Guten Morgen,
ich hänge mal wieder an einem "Encoding Fehler" fest.
Ich übertrage per XMLRPC einen String der Sonderzeichen enthält von einem Windows PC an einen Debian Server. Beide Programme sind mit coding iso-8859-1 codiert und gespeichert.
Das Windows Programm erhält den String per sys.argv von einem anderen Programm.
Mein Problem ist jetzt das die Sonderzeichen nicht übertragen werden bzw. der Fehler
xml.parsers.expat.ExpatError: not well-formed (invalid token)
ausgegeben wird. Auch div. umcodieren und wandeln in unicode etc. hat nicht den gewünschten Erfolg gebracht.
Codeschnippsel kann ich euch leider keine posten da das Script zu groß ist.
Für einen Denkanstoß wäre ich recht dankbar.
Gruß
Damaskus
encoding / xmlrpclib Problem
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Damaskus!Damaskus hat geschrieben:Ich übertrage per XMLRPC einen String der Sonderzeichen enthält von einem Windows PC an einen Debian Server... Für einen Denkanstoß wäre ich recht dankbar.
Ohne Code keine genaueren Hinweise. Aber hier ein paar Gedanken:
Irgendwo habe ich das mal gelesen -- ich weiß nicht mehr wo.
- XMLRPC erwartet UTF-8 codierte Strings.
- Der Server sollte UTF-8 erwarten und UTF-8 zurück geben.
- Der Client sollte UTF-8 erwarten und UTF-8 zurück geben.
Dann muss der String vorher von ``sys.getfilesystemencoding()`` über Unicode nach UTF-8 umgewandelt werden, bevor dieser über XMLRPC weitergereicht werden kann.Damaskus hat geschrieben:Das Windows Programm erhält den String per sys.argv von einem anderen Programm.
???Damaskus hat geschrieben:xml.parsers.expat.ExpatError: not well-formed (invalid token)
Das kann vieles sein. Aber schau dir doch mal das an, was XMLRPC aus deinem String macht. Das hilft mir beim Fehler finden:
Code: Alles auswählen
>>> xmlrpclib.dumps((u"öäü",))
'<params>\n<param>\n<value><string>\xc3\xb6\xc3\xa4\xc3\xbc</string></value>\n</param>\n</params>\n'
>>> xmlrpclib.dumps(("öäü",))
'<params>\n<param>\n<value><string>\xf6\xe4\xfc</string></value>\n</param>\n</params>\n'
>>> xmlrpclib.dumps((u"öäü".encode("utf-8"),))
'<params>\n<param>\n<value><string>\xc3\xb6\xc3\xa4\xc3\xbc</string></value>\n</param>\n</params>\n'
>>>
Und den Gedanken von Trundle würde ich auch nachverfolgen. Mit ``xmlrpclib.dumps`` hast du dafür ja ein Mittel in der Hand.
lg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- Damaskus
- Administrator
- Beiträge: 995
- Registriert: Sonntag 6. März 2005, 20:08
- Wohnort: Schwabenländle
Nabend,
nach langem Suchen an falscher Stelle hab ich den Fehler gefunden.
Es ist nicht XMLRPC dran schuld sondern die auf dem Server werden die Daten in ein Dictionary gepackt und von da aus dann per urlencode codiert.
Die Übernahme ins Dic. erfolgt automatisch in Unicode aber das abrufen der DAten mit urlencode decodiert den Unicode String leider nicht.
Codeschnippsel gibts morgen dazu.
Gruß
Damaskus
nach langem Suchen an falscher Stelle hab ich den Fehler gefunden.
Es ist nicht XMLRPC dran schuld sondern die auf dem Server werden die Daten in ein Dictionary gepackt und von da aus dann per urlencode codiert.
Die Übernahme ins Dic. erfolgt automatisch in Unicode aber das abrufen der DAten mit urlencode decodiert den Unicode String leider nicht.
Codeschnippsel gibts morgen dazu.
Gruß
Damaskus
- Damaskus
- Administrator
- Beiträge: 995
- Registriert: Sonntag 6. März 2005, 20:08
- Wohnort: Schwabenländle
So nach etwas hin und her weiss ich nicht mehr richtig weiter.
Wenn ich folgendes Script ausführe funktioniert alles wie gewünscht:
übertrage ich s1, s2, s3 mit XMLRPC vom Client zum Server dann kann er das Dic. nicht richtig verarbeiten.
Hat jemand eine Idee dazu?
Gruß
Damaskus
Wenn ich folgendes Script ausführe funktioniert alles wie gewünscht:
Code: Alles auswählen
import urllib
s1 = "Ich bin ein Test"
s2 = "Ich bin der gleiche Test mit ä"
s3 = "Und ich mit öü und ß"
print s3
>>> Und ich mit öü und ß
data = {}
data["s1"] = s1
data["s2"] = s2
data["s3"] = s3
print data
>>> {'s3': 'Und ich mit \xc3\xb6\xc3\xbc und \xc3\x9f', 's2': 'Ich bin der gleiche Test mit \xc3\xa4', 's1': 'Ich bin ein Test'}
s4 = urllib.urlencode(data)
print s4
>>> s3=Und+ich+mit+%C3%B6%C3%BC+und+%C3%9F&s2=Ich+bin+der+gleiche+Test+mit+%C3%A4&s1=Ich+bin+ein+Test
Hat jemand eine Idee dazu?
Gruß
Damaskus
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Damaskus!
Warum ``urllib``?
mfg
Gerold
Warum ``urllib``?
Code: Alles auswählen
>>> import xmlrpclib as x
>>> xml = x.dumps(
... (
... {
... 's3': 'Und ich mit \xc3\xb6\xc3\xbc und \xc3\x9f',
... 's2': 'Ich bin der gleiche Test mit \xc3\xa4',
... 's1': 'Ich bin ein Test'
... },
... )
... )
>>> x.loads(xml)
(({'s3': u'Und ich mit \xf6\xfc und \xdf',
's2': u'Ich bin der gleiche Test mit \xe4',
's1': 'Ich bin ein Test'},), None)
>>>
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
server.py:
client.py:
Ausgabe am Client:
Wenn Server und Client Pythonprogramme sind, dann gilt:
Unicode rein -- Unicode raus
mfg
Gerold
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
from SimpleXMLRPCServer import SimpleXMLRPCServer
from random import randint
def get_data():
d = {
"s1": u"Ich bin am Client zwar nicht Unicode, aber ohne Fehler konvertierbar",
"s2": u"Ich bin der gleiche Test mit ä (ich bin Unicode)",
"s3": u"Und ich mit öü und ß (ich bin Unicode)",
}
return d
server = SimpleXMLRPCServer(("localhost", 50505))
server.register_function(get_data)
print "Der XMLRPC-Server horcht auf http://localhost:50505."
print "Er kann mit STRG+C beendet werden."
server.serve_forever()
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import socket
socket.setdefaulttimeout(3) # Timeout auf 3 sec. setzen
import xmlrpclib
server = xmlrpclib.ServerProxy("http://localhost:50505")
print server.get_data()
Code: Alles auswählen
{'s3': u'Und ich mit \xf6\xfc und \xdf (ich bin Unicode)',
's2': u'Ich bin der gleiche Test mit \xe4 (ich bin Unicode)',
's1': 'Ich bin am Client zwar nicht Unicode, aber ohne Fehler konvertierbar'}
Unicode rein -- Unicode raus
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- Damaskus
- Administrator
- Beiträge: 995
- Registriert: Sonntag 6. März 2005, 20:08
- Wohnort: Schwabenländle
Hallo Gerold,
ich glaub ich hab mein Problem falsch geschildert.
Anfangs dachte ich der Fehler liegt an der Übertragung der Sonderzeichen per XMLRPC. War aber ein Fehler von mir, die Übertragung zwischen Client und Server funktioniert problemlos. Hier werden die Daten automatisch per Unicode übertragen.
Später hab ich festgestellt das der Fehler nur in Kombination folgender Schritte auftritt und eher bei urllib.urlencode zu suchen ist.
1. übergabe der Strings per sys.argv
2. übertragung von Windows Client auf Debian Server per xmlrpc (beides Python)
3. Strings in ein Dictionary packen
4. Strings aus dem Dictionary mit urllib.urlencode zu einem HTTP Request umschreiben
server.py
client.py
Ich hoffe das obiges Bsp. den Fehler aufzeigt.
Gruß
Damaskus
ich glaub ich hab mein Problem falsch geschildert.
Anfangs dachte ich der Fehler liegt an der Übertragung der Sonderzeichen per XMLRPC. War aber ein Fehler von mir, die Übertragung zwischen Client und Server funktioniert problemlos. Hier werden die Daten automatisch per Unicode übertragen.
Später hab ich festgestellt das der Fehler nur in Kombination folgender Schritte auftritt und eher bei urllib.urlencode zu suchen ist.
1. übergabe der Strings per sys.argv
2. übertragung von Windows Client auf Debian Server per xmlrpc (beides Python)
3. Strings in ein Dictionary packen
4. Strings aus dem Dictionary mit urllib.urlencode zu einem HTTP Request umschreiben
server.py
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
from SimpleXMLRPCServer import SimpleXMLRPCServer
import urllib
def mach_was(s1, s2, s3):
data = {}
data["s1"] = s1
data["s2"] = s2
data["s3"] = s3
link = "http://www.test.de/script.php"
s4 = urllib.urlencode(data)
return True
server = SimpleXMLRPCServer(("localhost", 50505))
server.register_function(mach_was)
print "Der XMLRPC-Server horcht auf http://localhost:50505."
print "Er kann mit STRG+C beendet werden."
server.serve_forever()
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import socket
socket.setdefaulttimeout(3) # Timeout auf 3 sec. setzen
import xmlrpclib
server = xmlrpclib.ServerProxy("http://localhost:50505")
s1 = u"Ich bin ein Test"
s2 = u"Ich bin der gleiche Test mit ä"
s3 = u"Und ich mit öü und ß"
server.mach_was(s1, s2, s3)
Gruß
Damaskus
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Damaskus!
So wie es aussieht, kann urllib nichts mit Unicode anfangen. Ich halte das für schlampig und einen Bug.
Ich habe da mal ein wenig getestet:
Übergibt man an ``urllib.urlencode`` ein Dictionary mit Unicode, dann wirft es einen Fehler.
Übergibt man an ``urllib.urlencode`` ein dictionary mit UTF-8- oder ISO-8859-1-Bytestrings, dann liefert es je ein Ergebnis. Leider zwei verschiedene Ergebnisse.
Im Internet Explorer kann man einstellen, ob URLs immer als UTF-8 übertragen werden sollen. Daraus schließe ich, dass du evt. zu einem guten Ergebnis kommen könntest, wenn du die Strings vor dem Umwandeln mit ``urllib.urlencode`` nach UTF-8 umwandelst. Aber trotzdem finde ich das Verhalten von ``urllib.urlencode`` für dringend nachbesserungswürdig. Da gehört unbedingt noch Unicodehandling rein.
lg,
Gerold
So wie es aussieht, kann urllib nichts mit Unicode anfangen. Ich halte das für schlampig und einen Bug.
Ich habe da mal ein wenig getestet:
Code: Alles auswählen
>>> import urllib
>>> data = {
... "s1": u"Ich bin ein Test",
... "s2": u"Ich bin der gleiche Test mit ä",
... "s3": u"Und ich mit öü und ß"
... }
>>> data
{'s3': u'Und ich mit \xf6\xfc und \xdf', 's2': u'Ich bin der gleiche Test mit \xe4', 's1': u'Ich bin ein Test'}
>>> urllib.urlencode(data)
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "J:\Python25\lib\urllib.py", line 1250, in urlencode
v = quote_plus(str(v))
UnicodeEncodeError: 'ascii' codec can't encode characters in position 12-13: ordinal not in range(128)
>>> data = {
... "s1": u"Ich bin ein Test".encode("utf-8"),
... "s2": u"Ich bin der gleiche Test mit ä".encode("utf-8"),
... "s3": u"Und ich mit öü und ß".encode("utf-8")
... }
>>> data
{'s3': 'Und ich mit \xc3\xb6\xc3\xbc und \xc3\x9f', 's2': 'Ich bin der gleiche Test mit \xc3\xa4', 's1': 'Ich bin ein Test'}
>>> urllib.urlencode(data)
's3=Und+ich+mit+%C3%B6%C3%BC+und+%C3%9F&s2=Ich+bin+der+gleiche+Test+mit+%C3%A4&s1=Ich+bin+ein+Test'
>>> data = {
... "s1": u"Ich bin ein Test".encode("iso-8859-1"),
... "s2": u"Ich bin der gleiche Test mit ä".encode("iso-8859-1"),
... "s3": u"Und ich mit öü und ß".encode("iso-8859-1")
... }
>>>
>>> urllib.urlencode(data)
's3=Und+ich+mit+%F6%FC+und+%DF&s2=Ich+bin+der+gleiche+Test+mit+%E4&s1=Ich+bin+ein+Test'
>>>
Übergibt man an ``urllib.urlencode`` ein dictionary mit UTF-8- oder ISO-8859-1-Bytestrings, dann liefert es je ein Ergebnis. Leider zwei verschiedene Ergebnisse.
Im Internet Explorer kann man einstellen, ob URLs immer als UTF-8 übertragen werden sollen. Daraus schließe ich, dass du evt. zu einem guten Ergebnis kommen könntest, wenn du die Strings vor dem Umwandeln mit ``urllib.urlencode`` nach UTF-8 umwandelst. Aber trotzdem finde ich das Verhalten von ``urllib.urlencode`` für dringend nachbesserungswürdig. Da gehört unbedingt noch Unicodehandling rein.
lg,
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- Damaskus
- Administrator
- Beiträge: 995
- Registriert: Sonntag 6. März 2005, 20:08
- Wohnort: Schwabenländle
Hallo Gerold,
genau so etwas in der Art habe ich vermutet.
Ich hab das Problem jetzt folgendermaßen gelöst.
server.py:
Jetzt muss ich nur noch testen welches Coding der Server der den Request erhält korrekt verarbeitet, was aber kein Problem. Das ganze Steuert dann ein SMS Gateway.
Danke für die Hilfe!
Gruß
Damaskus
genau so etwas in der Art habe ich vermutet.
Ich hab das Problem jetzt folgendermaßen gelöst.
server.py:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
from SimpleXMLRPCServer import SimpleXMLRPCServer
import urllib
def mach_was(s1, s2, s3):
print s1, s2, s3
data = {}
data["s1"] = s1.encode("utf-8")
data["s2"] = s2.encode("utf-8")
data["s3"] = s3.encode("utf-8")
link = "http://www.test.de/script.php"
print data
s4 = urllib.urlencode(data)
print s4
return True
server = SimpleXMLRPCServer(("localhost", 50505))
server.register_function(mach_was)
print "Der XMLRPC-Server horcht auf http://localhost:50505."
print "Er kann mit STRG+C beendet werden."
server.serve_forever()
Danke für die Hilfe!
Gruß
Damaskus