Essayer de créer un bot Twitter qui lit les lignes et les poste. En utilisant Python3 et tweepy, via un virtualenv sur mon espace serveur partagé. C'est la partie du code qui semble avoir des problèmes:
#!/foo/env/bin/python3
import re
import tweepy, time, sys
argfile = str(sys.argv[1])
filename=open(argfile, 'r')
f=filename.readlines()
filename.close()
c'est l'erreur que j'obtiens:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xfe in position 0: ordinal not in range(128)
L'erreur pointe spécifiquement sur f=filename.readlines()
comme source de l'erreur. Une idée de ce qui pourrait être faux? Merci.
Je pense que la meilleure réponse (en Python 3) est d'utiliser le paramètre errors=
:
with open('evil_unicode.txt', 'r', errors='replace') as f:
lines = f.readlines()
Preuve:
>>> s = b'\xe5abc\nline2\nline3'
>>> with open('evil_unicode.txt','wb') as f:
... f.write(s)
...
16
>>> with open('evil_unicode.txt', 'r') as f:
... lines = f.readlines()
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/codecs.py", line 319, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe5 in position 0: invalid continuation byte
>>> with open('evil_unicode.txt', 'r', errors='replace') as f:
... lines = f.readlines()
...
>>> lines
['�abc\n', 'line2\n', 'line3']
>>>
Notez que le errors=
peut être replace
ou ignore
. Voici à quoi ressemble ignore
:
>>> with open('evil_unicode.txt', 'r', errors='ignore') as f:
... lines = f.readlines()
...
>>> lines
['abc\n', 'line2\n', 'line3']
Votre codage par défaut semble être ASCII, où l'entrée est plus que probable UTF-8. Lorsque vous frappez des octets non-ASCII dans l'entrée, l'exception est levée. Ce n'est pas tant que readlines
soit lui-même responsable du problème; au contraire, le décodage lecture + se produit et le décodage échoue.
C'est une solution facile cependant; La valeur par défaut open
dans Python 3 vous permet de fournir la encoding
connue d'une entrée, en remplaçant la valeur par défaut (ASCII dans votre cas) par tout autre codage reconnu. Cela vous permet de continuer à lire en tant que str
(plutôt que les objets bytes
de données binaires brutes très différents), tout en laissant Python se charger de la conversion d'octets de disque brut en données en texte vrai:
# Using with statement closes the file for us without needing to remember to close
# explicitly, and closes even when exceptions occur
with open(argfile, encoding='utf-8') as inf:
f = inf.readlines()
J'ai fini par trouver une solution de travail pour moi-même:
filename=open(argfile, 'rb')
Ce post m'a beaucoup aidé.