Bienvenue sur IndexError.

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

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

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 c0da (2,744 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 (4,974 points)
...