2017-09-02 1 views
1

J'ai écrit le programme python le plus simple qui présente l'erreur pour laquelle j'ai besoin d'aide.Le fichier python open() déclenche une exception pour le caractère non utf-8

lines_read = 0 
urllist_file = open('../fall11_urls.txt', 'r') 

for line in urllist_file: 
    lines_read += 1 
print('line count:', lines_read) 

je lance ceci sur la plupart des fichiers et bien sûr, il fonctionne comme prévu, mais « fall11_urls.txt » est un fichier texte de 14 millions de ligne qui contient des URL, une par ligne. Certaines de ces lignes contiennent du texte avec des caractères qui ne sont pas utf-8 et je reçois l'erreur citée ci-dessous. J'ai besoin d'accéder à chacune de ces URL Quelle est la meilleure façon de gérer cela. Ces URL peuvent être "quelque chose" certains sont 400 caractères de caractères aléatoires comme dans "https://bbswigr.fty.com/_Kcsnuk4J71A/RjzGhXZGmfI/AAAARg/xP3FO-Xbt68/s320/Axolo.jpg Certains de ces caractères contiennent des chaînes telles que 0x96 J'ai besoin de mon programme python pour être robuste contre tout ce qui pourrait être dans le fichier. Ubuntu 16.04)

Voici l'erreur

Traceback (most recent call last): 
    File "./count_lines.py", line 2, in <module> 
    for line in urllist_file: 
    File "/home/chris/.virtualenvs/cvml3/lib/python3.5/codecs.py", line 321, in decode 
    (result, consumed) = self._buffer_decode(data, self.errors, final) 
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 5529: invalid start byte 

un bit d'information iconv trouve le même problème avec le même dossier. Voir ci-dessous

$ iconv ../fall11_urls.txt >> /dev/null 
iconv: illegal input sequence at position 1042953625 

Mon travail actuel est d'environ UGLY. I utilisez iconv pour trouver le problème t Alors je main édite le fichier dans vi, puis le traite. et continuez à le faire jusqu'à ce qu'il soit propre mais j'ai des MILLIONS de lignes dans de nombreux fichiers à traiter. Et les URL fonctionnent surtout après que je les corrige à la main, donc ce ne sont pas du bruit ou des "bits retournés".

+1

Lire en tant que binaire, puis le décoder dans votre format requis – crook

+0

IMO le plus sain est d'utiliser 'errors = 'surrogateescape''. Il n'y a pas de * bons * moyens. – o11c

Répondre

0

Avez-vous essayé la méthode crook? Cela devrait fonctionner. urllist_file = open ('../ fall11_urls.txt', 'rb') puis convertir au format de votre choix

0

Répondre à ma propre question pour que vous sachiez ce qui a fonctionné. Oui l'ouverture en binaire a fonctionné, je l'ai essayé mais je n'ai pas de fichier "texte". J'ai lu sur l'encodage et trouvé les travaux suivants parce que chaque valeur de caractère binaire est valide. C'est la chose la plus sûre à faire.

urllist_file = open('../fall11_urls.txt', 'r', encoding="latin-1") 

Il semble que tout le monde l'ouverture des fichiers texte, ils obtenir d'autres personnes et ont aucun moyen de contrôler ou de savoir à l'avance ce qui est peut-être conseillé à l'intérieur d'utiliser « latin-1 » parce qu'il n'y a pas de valeurs d'octets non valides dans Latin-1.

Merci. La suggestion d'ouvrir en binaire m'a amené à étudier ce que d'autres paramètres open() accepte. Je suis nouveau à Python et étonné de constater que les chaînes sont juste une liste d'octets. (C'est ce que 20+ années de travail en C conditionneront à vous attendre.)

+0

Vous pouvez lire ceci [https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and -character-sets-no-excuses /). – Rishav