2009-11-04 20 views
1

J'essaye de formater un fichier pour qu'il puisse être inséré dans une base de données, le fichier est compressé à l'origine et a environ 1.3Mo de large. Chaque ligne ressemble à ceci:parse.unquote_plus TypeError

398,%7EAnoniem+001%7E,543,480,7525010,1775,0

Voici comment le code ressemble à celui parse ce fichier:

Village = gzip.open(Root+'\\data'+'\\' +str(Newest_Date[0])+'\\' +str(Newest_Date[1])+'\\' +str(Newest_Date[2])\ 
       +'\\'+str(Newest_Date[3])+' village.gz'); 
Village_Parsed = str 
for line in Village: 
    Village_Parsed = Village_Parsed + urllib.parse.unquote_plus(line); 
print(Village.readline()); 

Quand je lance le programme je reçois cette erreur:

Village_Parsed = Village_Parsed + urllib.parse.unquote_plus(line); 

file "C:\Python31\lib\urllib\parse.py", line 404, in unquote_plus string = string.replace('+', ' ') TypeError: expected an object with the buffer interface

Une idée de ce qui ne va pas ici? Merci d'avance pour toute aide :)

Répondre

0
import gzip, os, urllib.parse 

archive_relpath = os.sep.join(map(str, Newest_Date[:4])) + ' village.gz' 
archive_path = os.path.join(Root, 'data', archive_relpath) 

with gzip.open(archive_path) as Village: 
    Village_Parsed = ''.join(urllib.parse.unquote_plus(line.decode('ascii')) 
          for line in Village) 
    print(Village_Parsed) 

Sortie:

 
398,~Anoniem 001~,543,480,7525010,1775,0 

REMARQUE: RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax dit:

This specification does not mandate any particular character encoding for mapping between URI characters and the octets used to store or transmit those characters. When a URI appears in a protocol element, the character encoding is defined by that protocol; without such a definition, a URI is assumed to be in the same character encoding as the surrounding text.

Par conséquent 'ascii' dans le fragment line.decode('ascii') doit être remplacé par quelque encodage que vous avez utilisé pour encoder votre texte.

+0

@JFSebastian: Avez-vous déjà essayé? Je reçois exactement la même erreur que l'OP ... en dehors de son problème d'initialisation, votre code semble être fonctionnellement équivalent à son, retournant des objets octets. –

+0

@John Machin: Je l'ai essayé (maintenant). Je ne peux pas trouver 'unquote_plus_from_bytes' donc nous devons recourir à la méthode explicite' bytes.decode'. – jfs

+0

Merci, votre solution fonctionne très bien, et merci de signaler mes autres erreurs (Machin et Sebestian). Je ne suis pas sûr si ascii était l'encodage de caractères utilisé, mais cela fonctionne sans aucun problème pour autant que je puisse le voir. – user202459

2

PROBLEME 1 est que urllib.unquote_plus n'aime pas le line que vous avez nourri. Le message doit être « S'il vous plaît fournir un objet str » :-) Je vous suggère de résoudre le problème 2 ci-dessous, et insérer:

print('line', type(line), repr(line)) 

immédiatement après votre déclaration for afin que vous puissiez voir ce que vous obtenez en line.

Vous trouverez qu'il retourne octets objets:

>>> [line for line in gzip.open('test.gz')] 
[b'nudge nudge\n', b'wink wink\n'] 

En utilisant un mode de 'r' a un effet peu:

>>> [line for line in gzip.open('test.gz', 'r')] 
[b'nudge nudge\n', b'wink wink\n'] 

Je suggère qu'au lieu de passer line à la routine d'analyse syntaxique vous passez line.decode('UTF-8') ... ou quel que soit le codage utilisé lors de l'écriture du fichier gz.

PROBLEME 2 se trouve dans cette ligne:

Village_Parsed = str 

str est un type. Vous avez besoin d'un objet str vide. Pour obtenir cela, vous pouvez appeler le type-à-dire str() qui est formellement correcte mais peu pratique/inhabituelle/scoffable/bizarre par rapport à l'utilisation d'une chaîne '' constante ... donc faire:

Village_Parsed = '' 

Vous avez également PROBLÈME 3 : votre dernière déclaration essaie de lire le fichier gz après EOF.