Maison > Questions et réponses > le corps du texte
我需要使用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中似乎没有相关方法
各位可以调试一下
高洛峰2017-04-18 09:37:48
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 requests
models.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"}}
伊谢尔伦2017-04-18 09:37:48
Affichez tous les en-têtes et voyez. Il devrait y avoir un attribut charset.
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))
짱벶믵색
est coréen~~
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
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.
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~~
PHP中文网2017-04-18 09:37:48
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