Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

backslashreplace sur caratères accentués après un sys.stdin.read d'un POST en bytes

+2 votes

Je réalise une requête POST ainsi (requête non modifiable !) :

data_get = "?code=ovensia&feedtype=01"
data_post = bytes("<data><syn_eve>éà</syn_eve><syn_cour></syn_cour>/data>", "utf-8")
header = {'content-type': 'application/octet-stream'}
r = requests.post("http://monadresse/script.cgi/"+data_get, data=data_post, headers=header)
r.text

Et dans script.cgi :

xml_string = sys.stdin.read( int( os.environ.get( 'CONTENT_LENGTH', 0 )))
print(xml_string)

j'ai pas de résultat, nada ! pourquoi ?
si j'enlève les lettres accentuées dans data_post, j'obtiens le bon résultat :

<synergi><syn_evenement></syn_evenement><syn_maincourante></syn_maincourante></synergi>

Du coup après de looongues recherches j'ai essayé :

sys.stdin = codecs.getwriter("utf-8")(sys.stdin.detach())
xml_string  = sys.stdin.read( int( os.environ.get( 'CONTENT_LENGTH', 0 )))
print(xml_string)

Sans les lettres accentuées j'obtiens :

b'<synergi><syn_evenement></syn_evenement><syn_maincourante></syn_maincourante></synergi>'

Avec les lettres accentuées :

b'<synergi><syn_evenement>\\xc3\\xa9\\xc3\\xa0</syn_evenement><syn_maincourante></syn_maincourante></synergi>'

les backslashreplace rendent le résultat inutilisable, pas de decode possible ! Que faire ?

demandé 5-Fev-2016 par ajclibre (128 points)

3 Réponses

+3 votes

Ceci devrait t'aider:

>>> import re
>>> s = "b'<synergi><syn_evenement>\\xc3\\xa9\\xc3\\xa0</syn_evenement><syn_maincourante></syn_maincourante></synergi>'"
>>> t = re.sub(r'\\([!:])', r'\1', s)
>>> print t
b'<synergi><syn_evenement>\xc3\xa9\xc3\xa0</syn_evenement><syn_maincourante></syn_maincourante></synergi>'
répondu 6-Fev-2016 par barnumbirr (2,750 points)
0 votes

Après de très nombreuses recherches :
Ne pas faire de print() pour debugger ! C'est le print qui rajoute le double backslashreplace !
Utiliser logging à la place.
Concernant l'absence de réponse de sys.stdin.read() si il y a des accents il faut les catcher :

try :
sys.stdin.read()
except( UnicodeDecodeError ) :

Et voilà, c'est tout, je n'ai toujours pas réussi à afficher les accents. Cela lève une exception d'encodage malgré que :

>>> sys.stdin.encoding
'UTF-8'
>>> sys.getfilesystemencoding()
'utf-8'
répondu 10-Fev-2016 par ajclibre (128 points)
0 votes

Encore un qui n'a pas lu l'article sur l'encoding: sametmax.com/lencoding-en-python-une-bonne-fois-pour-toute/

Ta dernière solution est un bon début mais tu devrais utiliser getreader() et non getwritter() (ou encore plus simplement, io.StringIO(encoding="utf8")

répondu 17-Fev-2016 par Sam (5,000 points)
...