2016-01-26 1 views
4

Quand je lance ce code dans ipython (Python 2.7):Python get pose HTTPError 400 Erreur du client, mais après avoir accédé manuellement URL, vous obtiendrez des œuvres temporairement

from requests import get 
_get = get('http://stats.nba.com/stats/playergamelog', params={'PlayerID': 203083, 'Season':'2015-16', 'SeasonType':'Regular Season'}) 
print _get.url 
_get.raise_for_status() 
_get.json() 

Je reçois:

http://stats.nba.com/stats/playergamelog?PlayerID=203083&Season=2015-16&SeasonType=Regular+Season 
--------------------------------------------------------------------------- 
HTTPError         Traceback (most recent call last) 
<ipython-input-5-8f8343b2c4cd> in <module>() 
     1 _get = get('http://stats.nba.com/stats/playergamelog', params={'PlayerID': 203083, 'Season':'2015-16', 'SeasonType':'Regular Season'}) 
     2 print _get.url 
----> 3 _get.raise_for_status() 
     4 _get.json() 

/Library/Python/2.7/site-packages/requests/models.pyc in raise_for_status(self) 
    849 
    850   if http_error_msg: 
--> 851    raise HTTPError(http_error_msg, response=self) 
    852 
    853  def close(self): 

HTTPError: 400 Client Error: Bad Request 

Cependant, si je vais à l'URL dans mon navigateur, cela fonctionne. Puis, quand je reviens au code et le réexécute après avoir manuellement visité l'URL dans mon navigateur (Chrome sur lequel iPython s'exécute), le code s'exécute sans erreur. Toutefois, il peut revenir à augmenter l'erreur dans les exécutions séquentielles.

Ce code a fonctionné pour moi des centaines voire des milliers de fois sans problème. Comment réparer cette erreur?

Merci.

Répondre

3

HTTPError: 400 Client Error: Bad Request signifie que la requête que vous avez faite comporte une erreur. Et je pense que le serveur peut vérifier certains en-têtes dans la requête HTTP, par exemple le user-agent.

J'essayé de placer l'en-tête User-Agent pour imiter Firefox:

# No User-Agent 
>>> _get = get('http://stats.nba.com/stats/playergamelog', params={'PlayerID': 203082, 'Season':'2015-16', 'SeasonType':'Regular Season'}) 
>>> _get.raise_for_status() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\requests\models.py", line 840, in raise_for_status 
    raise HTTPError(http_error_msg, response=self) 
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: http://stats.nba.com/stats/playergamelog?PlayerID=203082&Season=2015-16&SeasonType=Regular+Season 

# This time, set user-agent to mimic a desktop browser 
>>> headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0'} 
>>> _get = get('http://stats.nba.com/stats/playergamelog', params={'PlayerID': 203082, 'Season':'2015-16', 'SeasonType':'Regular Season'}, headers=headers) 
>>> _get.raise_for_status() 
>>> 
# no error 

La raison pour laquelle il peut travailler après avoir visiter l'URL dans le navigateur est la mise en cache. Selon Alastair McCormack, stats.nba.com est précédé par Akamai CDN, de sorte que la mise en cache est probablement en cours sur le bord, "variée" par la chaîne de requête/URI plutôt que par des en-têtes extranous. Une fois qu'une réponse valide a été faite pour cet URI, il est mis en cache par le nœud d'extrémité CDN desservant ce client. Par conséquent, lorsque vous exécutez du code après avoir visité l'URL dans le navigateur, CDN vous renvoie la réponse mise en cache. aucun 400 ne sera élevé dans une telle situation.

+1

'stats.nba.com' est précédé par Akamai CDN, donc la mise en cache se passe probablement à la périphérie," variée "par la chaîne de requête/URI plutôt que par des en-têtes extranous. Une fois qu'une réponse valide a été faite pour cet URI, il est mis en cache par le nœud d'extrémité CDN desservant ce client. Il semble que le serveur nécessite qu'un agent utilisateur de type bureau soit configuré pour générer une réponse valide et donc un élément pouvant être mis en cache. Bon endroit! –

+0

@AlastairMcCormack, je pense que vous avez raison sur la mise en cache – realli

+0

Je pense que je comprends la logique que vous avez exposée, mais au cas où je ne le fais pas, d'un point de vue purement pratique, cela signifie que je ne devrais plus jamais rencontrer ce problème. spécifier un agent utilisateur valide? – andingo