Un bon moyen d'obtenir le jeu de caractères/de codage d'une réponse HTTP en Python
La recherche d'un moyen facile d'obtenir le jeu de caractères/de codage de l'information d'une réponse HTTP à l'aide de Python urllib2, ou de toute autre bibliothèque Python.
>>> url = 'http://some.url.value'
>>> request = urllib2.Request(url)
>>> conn = urllib2.urlopen(request)
>>> response_encoding = ?
Je sais que c'est parfois présent dans le "Content-Type" de la tête, mais que la tête a d'autres informations, et il est intégré dans une chaîne que j'aurais besoin de l'analyser. Par exemple, le Contenu de l'en-tête de Type retourné par Google est
>>> conn.headers.getheader('content-type')
'text/html; charset=utf-8'
Je pouvais travailler avec cela, mais je ne suis pas sûr de la façon cohérente le format sera. Je suis sûr que c'est possible pour le jeu de caractères à être totalement absente, alors j'aimerais avoir à gérer ce cas de bord. Une sorte de chaîne de l'opération de fractionnement pour obtenir le 'utf-8' de l', il semble comme il est à la mauvaise manière de faire ce genre de chose.
>>> content_type_header = conn.headers.getheader('content-type')
>>> if '=' in content_type_header:
>>> charset = content_type_header.split('=')[1]
C'est le genre de code qui se sent comme il fait trop de travail. Je suis également pas sûr si cela ne fonctionne pas dans tous les cas. Quelqu'un aurait-il une meilleure façon de le faire?
Vous devez vous connecter pour publier un commentaire.
Pour analyser l'en-tête http, vous pourriez utiliser
cgi.parse_header()
:Ou à l'aide de l'objet de réponse:
En général, le serveur peut mentir au sujet de l'encodage ou ne pas signaler à tous (valeur par défaut dépend du type de contenu) ou le codage peut être spécifié à l'intérieur du corps de la réponse par exemple,
<meta>
élément dans les documents html ou en xml de la déclaration pour les documents xml. En dernier recours, le codage peut être deviné à partir du contenu lui-même.Vous pouvez utiliser
demande
pour obtenir le texte Unicode:Ou
BeautifulSoup
pour parser le html (et de les convertir au format Unicode comme un effet secondaire):Ou
bs4.UnicodeDammit
directement de contenu arbitraire (pas nécessairement html):Si vous arrive d'être familier avec la Flacon/Werkzeug de développement web de la pile, vous serez heureux de savoir que les Werkzeug bibliothèque a une réponse pour exactement ce genre d'en-tête HTTP de l'analyse, et les comptes pour le cas où le contenu-type n'est pas spécifié à tous, comme vous l'aviez voulu.
Alors que vous pouvez faire:
Noter que si
charset
n'est pas fourni, ceci produira plutôt:Il fonctionne même si vous ne fournissez pas rien, mais une chaîne vide ou dict:
Ainsi, il semble être EXACTEMENT ce que vous cherchiez! Si vous regardez le code source, vous verrez qu'ils avaient à votre but à l'esprit: https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/http.py#L320-329
Espère que cela aide quelqu'un un jour! 🙂
La
demande
bibliothèque rend cela facile:requests.Response.apparent_encoding
.Les jeux de caractères peuvent être spécifiés dans de nombreuses façons, mais c'est souvent fait dans les en-têtes.
Que le dernier n'est pas en mesure de spécifier un jeu de caractères de n'importe où, donc
get_content_charset()
retournéNone
.<meta charset=..>
à l'intérieur d'un document html est plus susceptible d'être sous le contrôle de la personne qui a créé le document de du serveur les en-têtes. Il n'est pasget_content_charset()
en Python 2.cgi.parse_header()
fonctionne de la même façon sur Python 2 et 3.Correctement (c'est à dire dans un navigateur-comme - on ne peut pas faire mieux) le décodage de code html que vous devez prendre en compte:
<meta>
balises dans la page de corps;Tous les ci-dessus est mise en œuvre dans w3lib.l'encodage.html_to_unicode fonction: il a
html_to_unicode(content_type_header, html_body_str, default_encoding='utf8', auto_detect_fun=None)
signature et retourne(detected_encoding, unicode_html_content)
tuple.demandes, BeautifulSoup, UnicodeDamnnit, chardet ou flacon de parse_options_header ne sont pas correctes des solutions qu'ils ont tous échoué à certains de ces points.
C'est ce qui fonctionne parfaitement pour moi.
J'utilise python 2.7 et 3.4