python - requests headers 解码
黄舟
黄舟 2017-04-18 09:35:48
0
3
858

我需要使用python的requests 下载一些文件,但是文件是中文名的

chrome调试看出来的文件名是

Content-Disposition:attachment; filename=%C9%F1%BC%B6%BB%F5%C0%C9.txt

requests 下载显示的却是乱码

import requests
url = 'http://www.23us.so/modules/article/txtarticle.php?id=156'
req = requests.head(url)
headers = req.headers
print( headers.get('Content-Disposition'))

>> attachment; filename=ÇàÔÆÏÉ·.txt

我试过设置req.encoding 没有效果

怎么把header中的文字恢复出来,requests中似乎没有相关方法
各位可以调试一下

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

répondre à tous(3)
小葫芦

Ahem, vous auriez dû publier l'adresse spécifique du lien plus tôt, je vais suivre la méthode et mettre le code :

url = 'http://www.23us.so/modules/article/txtarticle.php?id=156'
req = requests.head(url)
headers = req.headers
print(headers.get('Content-Disposition').encode(req.encoding).decode('gbk'))  # gb2312也可以正确解码

Résultat :

attachment; filename=青云仙路.txt

Vous pouvez simplement laisser req.encoding deviner la méthode d'encodage de la cible. Le commentaire sur la ligne 769 de
du module requestsmodels.py indique très clairement que les gens peuvent détecter automatiquement le type d'encodage du. contenu de la page Web cible, et le code spécifique responsable de la détection de l'encodage est ici universaldetector.py
, il suffit donc d'utiliser cette fonctionnalité pour encoder puis d'appuyer sur utf-8 pour décoder. >

import requests


url = "http://www.weather.com.cn/data/cityinfo/101010100.html"
req = requests.get(url)
print(req.text)
print(req.encoding)
print(req.text.encode(req.encoding))
print(req.text.encode(req.encoding).decode('utf-8'))
Résultat :

{"weatherinfo":{"city":"北京","cityid":"101010100","temp1":"-2℃","temp2":"16℃","weather":"晴","img1":"n0.gif","img2":"d0.gif","ptime":"18:00"}}
ISO-8859-1
b'{"weatherinfo":{"city":"\xe5\x8c\x97\xe4\xba\xac","cityid":"101010100","temp1":"-2\xe2\x84\x83","temp2":"16\xe2\x84\x83","weather":"\xe6\x99\xb4","img1":"n0.gif","img2":"d0.gif","ptime":"18:00"}}'
{"weatherinfo":{"city":"北京","cityid":"101010100","temp1":"-2℃","temp2":"16℃","weather":"晴","img1":"n0.gif","img2":"d0.gif","ptime":"18:00"}}
伊谢尔伦

Affichez tous les en-têtes et voyez. Il devrait y avoir un attribut charset.


Mise à jour

Il s'agit en fait d'un encodage URI, qui est échappé de l'Unicode.
L'exemple de décodage est le suivant :

def decodeURI(strURI):
    strURI = strURI.replace('%','')
    URI = ''.join((chr(int(strURI[i:i+4],16)) for i in range(0,len(strURI),4)))
    return URI

n = '%C9%F1%BC%B6%BB%F5%C0%C9'
print(decodeURI(n))

Résultat :

짱벶믵색
est coréen~~


Plus de mises à jour

Après y avoir bien réfléchi, il pourrait s'agir d'un autre format d'encodage, alors j'ai essayé avec gb2312.

n = '%C9%F1%BC%B6%BB%F5%C0%C9'
print(bytes.fromhex(n.replace('%','')).decode('gb2312'))

Le résultat est :

神级货郎

Je pense que c'est plus fiable~
Ces méthodes sont disponibles dans urllib, à savoir : quote, unquote
Exemple :

import urllib

n = 'filename=%C9%F1%BC%B6%BB%F5%C0%C9.txt'
filename = urllib.parse.unquote(n,encoding='gb2312')
print(filename)

Le résultat est :

filename=神级货郎.txt

Trois mises à jour

J'explique le principe~
Quand on ne sait pas charset, on ne peut que deviner ; les requêtes utilisent également chardet pour deviner.
De plus, ce que @ferstar a dit req.encoding est pour 响应体(Response.content), pas pour headers.
Avant que Asker ne fournisse le code et le lien Web, je ne pouvais utiliser que les données fournies par Asker :

filename=%C9%F1%BC%B6%BB%F5%C0%C9.txt

Regardez bien, c'est un 字符串, pas un bytes ! Donc req.encoding n'est pas valide.
Comme je l'ai mentionné précédemment, il s'agit en fait d'un URI, qui est échappé d'un certain encodage du caractère original . % est le URI caractère d'échappement pour .
J'ai déjà écrit la méthode de restauration ci-dessus, et le résultat est correct.

Pourquoi ne pas accepter la bonne réponse ?

Pourquoi ne pas accepter la bonne réponse ?

Pourquoi ne pas accepter la bonne réponse ?


Quatre

Je ne voulais pas mettre à jour ce post, mais @ferstar a fait un long commentaire, il serait donc inapproprié de ne pas répondre~

Après que le questionneur a mis à jour et amélioré la question, j'ai suivi la réponse à temps et j'ai pu obtenir le résultat correct et résoudre le problème du questionneur. C'est un fait avant que le questionneur n'accepte ma réponse ; , votre réponse ne semble pas Il n'y a pas de mise à jour, ce qui est également un fait ; j'ai déjà publié l'implémentation spécifique du code source correspondant, ce qui est également raisonnable, et c'est encore plus vrai la méthode req.encoding que j'ai mentionnée joue un rôle ; rôle, et ce n'est pas inutile pour les en-têtes comme vous l'avez dit Cela semble être vrai

.

Citation du commentaire de @ferstar, complété

Les mises à jour de contenu SF ont des enregistrements de versions historiques, consultez-les et comparez-les.
Demandeur : ider
Réponse : D'accord et accepter
Réponse : ferstar

3 heures après avoir mis à jour la bonne réponse #r3, @ider a mis à jour la question #r4 et 采纳republié la première version de @ferstar de la réponse incorrecte #r1.
采纳Après cela, j'ai soulevé l'objection dans les commentaires et @ferstar a mis à jour la deuxième version de la réponse #r2.
De plus, la deuxième réponse de @ferstar est toujours fausse

Mais pourquoi la deuxième version de la réponse de @ferstar donne-t-elle le bon résultat ?
Parce que j'ai trouvé le bon encodage gb2312 auparavant, il vient de le remplacer par un encodage compatible gbk.

De plus, req.encoding ne peut pas agir sur headers.
Cette conclusion reste inchangée. Ceci est déterminé par le principe http, headers précède body.

Quant à la bonne façon d'écrire ce programme, j'ai la flemme de l'expliquer et de le mettre à jour, fatigué !
À moins que @ider ne réadopte ma réponse, je pourrais l'envisager~~

洪涛

Votre nom de fichier est codé en utilisant gb2312, et votre décodage doit également être configuré pour décoder selon gb2312. S'il est décodé selon utf-8, des caractères tronqués apparaîtront. Peut-être avez-vous défini le décodage pour décoder selon utf-8 par défaut

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal