9 votes

La bibliothèque de demandes Python a ajouté un en-tête supplémentaire "Accept-Encoding: identity"

Ceci est mon code.

import requests
from sys import exit
proxies = {
    "http": "127.0.0.1:8888",
    "https": "127.0.0.1:8888",
}

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0",
    "Accept-Encoding": "gzip, deflate",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.5",
    "Connection": "keep-alive"
}

login_page = "http://www.test.com/login/"
r = requests.get(login_page, proxies = proxies, headers = headers)
original_cookies = r.cookies
exit(0)

C'est ce que j'ai obtenu de Fiddler2. Comme vous pouvez le voir, il a ajouté un en-tête supplémentaire Accept-Encoding: identity.

GET http://www.test.com/login/ HTTP/1.1
Accept-Encoding: identity
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Host: www.test.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0

Je utilise Python 3.3.2 sur Windows 7 64 bits et requests 1.2.3.

Quelqu'un peut-il donner quelques suggestions?

Merci.

6voto

mata Points 22446

Cela provient du plus profond des entrailles de http.client, qui est utilisé par urllib3 qui est utilisé par requests.

http.client vérifie en fait si il y a déjà un accept-encoding dans le dictionnaire des en-têtes passé, et s'il y en a un, il évite d'ajouter l'en-tête identity - le seul problème est que ce qui est passé en tant que dictionnaire d'en-têtes ressemble à ceci:

CaseInsensitiveDict({b'Accept-Encoding': 'gzip, deflate, compress', ...})

Alors pourquoi cela ne fonctionne-t-il pas? requests encode les noms des en-têtes, et comme en python3 un objet str comparé à un objet bytes est toujours False, la vérification effectuée dans http.client échoue...

Si vous voulez vraiment vous débarrasser de l'en-tête supplémentaire, la manière la plus rapide serait de commenter la ligne 340 dans requests/models.py, ou de modifier dynamiquement requests.models.PreparedRequest.prepare_headers

edit:
cela semble être corrigé dans la branche 2.0 de requests (qui n'a pas encore été publiée)

0voto

Gleb Ignatev Points 105

Merci à la réponse de @mata, j'ai pu patché monkey HTTPConnection.putheader pour ignorer Accept-Encoding: identity dans mon cas particulier :

from http.client import HTTPConnection

def drop_accept_encoding_on_putheader(http_connection_putheader):
    def wrapper(self, header, *values):
        if header == "Accept-Encoding" and "identity" in values:
            return
        return http_connection_putheader(self, header, *values)

    return wrapper

HTTPConnection.putheader = drop_accept_encoding_on_putheader(HTTPConnection.putheader)

s = requests.Session()
s.headers.clear()
r = s.post("https://httpbin.org/post")
print(r.json()["headers"])

Résultat :

{'Content-Length': '0',
 'Host': 'httpbin.org',
 'User-Agent': 'python-urllib3/1.26.8',
 'X-Amzn-Trace-Id': 'Root=1-639e06af-32dea6906aff32526a081e8e'}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X