Pouvons-nous obtenir la valeur réelle utilisée pour link
?
En outre, nous avons l'habitude de rencontrer ce problème lorsque nous essayons d' .encode()
déjà codé chaîne d'octets. Donc, vous pourriez essayer de décrypter, d'abord en
html = urllib.urlopen(link).read()
unicode_str = html.decode(<source encoding>)
encoded_str = unicode_str.encode("utf8")
À titre d'exemple:
html = '\xa0'
encoded_str = html.encode("utf8")
Échoue avec
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
Alors que:
html = '\xa0'
decoded_str = html.decode("windows-1252")
encoded_str = decoded_str.encode("utf8")
Réussit sans erreur. Notez que "windows-1252" est quelque chose que j'ai utilisé comme un exemple. J'ai obtenu ce à partir de chardet et il avait de 0,5 confiance qu'il est bon! (eh bien, comme avec un 1 caractères chaîne de longueur, qu'attendez-vous de), Vous devez modifier que l'encodage de la chaîne d'octets renvoyés à partir de .urlopen().read()
pour ce qui concerne le contenu que vous avez récupéré.
Un autre problème que je vois, il n'y a que l' .encode()
chaîne de méthode renvoie la chaîne modifiée et ne pas modifier la source. Il est donc inutile d'avoir self.response.out.write(html)
que le html n'est pas la chaîne codée en html.coder (si c'est ce que vous avez été à l'origine de viser).
Comme Ignacio proposé, vérifier la source de la page web pour l'encodage réel de la chaîne renvoyée par read()
. C'est dans l'un des balises Meta-tags ou dans le ContentType tête dans la réponse. Utiliser ensuite comme paramètre .decode()
.
Notez cependant qu'il ne faut pas croire que les autres développeurs sont assez responsable pour s'assurer de l'en-tête et/ou méta-jeu de caractères déclarations correspondre au contenu réel. (Qui est un pain PITA, ouais, je sais, j'ai été l'un de ceux d'avant).