recherche

Maison  >  Questions et réponses  >  le corps du texte

python - requests headers 解码

我需要使用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中似乎没有相关方法
各位可以调试一下

黄舟黄舟2803 Il y a quelques jours875

répondre à tous(3)je répondrai

  • 高洛峰

    高洛峰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 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"}}
    

    répondre
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 09:37:48

    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~~

    répondre
    0
  • PHP中文网

    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

    répondre
    0
  • Annulerrépondre