J'utilise actuellement Beautiful Soup pour analyser un fichier HTML et appeler get_text()
, mais il me semble qu'il me reste beaucoup de \ xa0 Unicode représentant des espaces. Existe-t-il un moyen efficace de les supprimer tous en Python 2.7 et de les transformer en espaces? Je suppose que la question la plus générale serait: existe-t-il un moyen de supprimer le formatage Unicode?
J'ai essayé d'utiliser line = line.replace(u'\xa0',' ')
:, comme suggéré par un autre thread, mais cela a changé les \ xa0 en u, donc maintenant j'ai des "u" partout à la place. ):
EDIT: Le problème semble être résolu par str.replace(u'\xa0', ' ').encode('utf-8')
, mais le simple fait de s'en .encode('utf-8')
passer replace()
semble le faire cracher des caractères encore plus étranges, \ xc2 par exemple. Quelqu'un peut-il expliquer cela?
u''
s au lieu de''
s. :-)u' '
remplacement, pas le' '
. La chaîne d'origine est-elle unicode?Réponses:
\ xa0 est en fait un espace insécable en Latin1 (ISO 8859-1), également chr (160). Vous devez le remplacer par un espace.
string = string.replace(u'\xa0', u' ')
Lorsque .encode ('utf-8'), il encodera l'unicode en utf-8, cela signifie que chaque unicode pourrait être représenté par 1 à 4 octets. Dans ce cas, \ xa0 est représenté par 2 octets \ xc2 \ xa0.
Lisez sur http://docs.python.org/howto/unicode.html .
Remarque: cette réponse datant de 2012, Python a évolué, vous devriez pouvoir l'utiliser
unicodedata.normalize
maintenantla source
b'\xa0'
octets dans le codage latin1, en deux octetsb'\xc2\xa0'
dans le codage utf-8. Il peut être représenté comme
en html.UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 397: ordinal not in range(128)
.Il y a beaucoup de choses utiles dans la
unicodedata
bibliothèque de Python . L'un d'eux est la.normalize()
fonction.Essayer:
Remplacer NFKD par l'une des autres méthodes répertoriées dans le lien ci-dessus si vous n'obtenez pas les résultats que vous recherchez.
la source
normalize('NFKD', '1º\xa0dia')
être retourner '1º dia' mais cela retourne '1o dia'unicodedata.normalize
Essayez d'utiliser .strip () à la fin de votre ligne
line.strip()
a bien fonctionné pour moila source
Après avoir essayé plusieurs méthodes, pour le résumer, voici comment je l'ai fait. Voici deux façons d'éviter / supprimer les caractères \ xa0 de la chaîne HTML analysée.
Supposons que nous ayons notre html brut comme suit:
Essayons donc de nettoyer cette chaîne HTML:
Le code ci-dessus produit ces caractères \ xa0 dans la chaîne. Pour les supprimer correctement, nous pouvons utiliser deux méthodes.
Méthode n ° 1 (recommandée): la première est la méthode get_text de BeautifulSoup avec l' argument strip comme True. Notre code devient donc:
Méthode n ° 2: L'autre option consiste à utiliser la bibliothèque unicodedata de python
J'ai également détaillé ces méthodes sur ce blog que vous voudrez peut-être consulter.
la source
essaye ça:
la source
len(b'\\xa0') == 4
maislen(b'\xa0') == 1
. Si possible; vous devez corriger en amont qui génère ces échappements.J'ai rencontré ce même problème lors de l'extraction de certaines données d'une base de données sqlite3 avec python. Les réponses ci-dessus n'ont pas fonctionné pour moi (je ne sais pas pourquoi), mais cela a fonctionné:
line = line.decode('ascii', 'ignore')
Cependant, mon objectif était de supprimer les \ xa0s, plutôt que de les remplacer par des espaces.Je l'ai obtenu grâce à ce tutoriel Unicode super utile de Ned Batchelder.
la source
'ignore'
c'est comme pousser à travers le levier de vitesse même si vous ne comprenez pas comment fonctionne l'embrayage.str.encode(..., 'ignore')
est l'équivalent de la gestion Unicode detry: ... except: ...
. Bien qu'il puisse masquer le message d'erreur, il résout rarement le problème..decode('ascii', 'ignore')
line.decode()
dans votre réponse suggère que votre entrée est un bytestring (vous ne devez pas faire appel.decode()
à une chaîne Unicode (pour l'appliquer, la méthode est supprimée en Python 3). Je ne comprends pas comment il est possible de voir le tutoriel que vous avez lié dans votre réponse et manquez la différence entre les octets et Unicode (ne les mélangez pas)Je me retrouve ici en recherchant le problème avec le caractère non imprimable. J'utilise MySQL
UTF-8
general_ci
et m'occupe du langage polonais. Pour les chaînes problématiques, je dois procéder comme suit:C'est juste une solution de contournement rapide et vous devriez probablement essayer quelque chose avec la bonne configuration d'encodage.
la source
text
est un bytestring qui représente un texte encodé en utilisant utf-8. Si vous travaillez avec du texte; le décoder en Unicode first (.decode('utf-8')
) et le coder en un bytestring uniquement à la fin (si l'API ne prend pas directement en charge Unicode, par exemple,socket
). Toutes les opérations intermédiaires sur le texte doivent être effectuées sur Unicode.Essayez ce code
la source
0xA0 (Unicode) est 0xC2A0 en UTF-8.
.encode('utf8')
prendra simplement votre Unicode 0xA0 et le remplacera par 0xC2A0 de l'UTF-8. D'où l'apparition de 0xC2s ... L'encodage ne remplace pas, comme vous l'avez probablement réalisé maintenant.la source
0xc2a0
est ambigu (ordre des octets). Utilisezb'\xc2\xa0'
plutôt des octets littéraux.C'est l'équivalent d'un caractère d'espace, alors dépouillez-le
la source
Dans Beautiful Soup, vous pouvez passer
get_text()
le paramètre strip, qui supprime les espaces blancs du début et de la fin du texte. Cela supprimera\xa0
ou tout autre espace blanc s'il se produit au début ou à la fin de la chaîne. Beautiful Soup a remplacé une chaîne vide par\xa0
et cela a résolu le problème pour moi.la source
strip=True
ne fonctionne que si se
trouve au début ou à la fin de chaque bit de texte. Il ne supprimera pas l'espace s'il se trouve entre d'autres caractères du texte.Version générique avec l'expression régulière (elle supprimera tous les caractères de contrôle):
la source
Python le reconnaît comme un caractère d'espace, vous pouvez
split
donc le faire sans arguments et le joindre par un espace blanc normal:la source