Python get会引发HTTPError 400客户端错误,但在手动访问URL后,get会临时工作

Python get会引发HTTPError 400客户端错误,但在手动访问URL后,get会临时工作,python,json,ipython,python-requests,http-error,Python,Json,Ipython,Python Requests,Http Error,在iPython(Python 2.7)中运行此代码时: 我得到: http://stats.nba.com/stats/playergamelog?PlayerID=203083&Season=2015-16&SeasonType=Regular+Season --------------------------------------------------------------------------- HTTPError

在iPython(Python 2.7)中运行此代码时:

我得到:

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
http://stats.nba.com/stats/playergamelog?PlayerID=203083&Season=2015-16和季节类型=常规+季节
---------------------------------------------------------------------------
HTTPError回溯(最近一次调用上次)
在()
1 _get=get('http://stats.nba.com/stats/playergamelog“,参数={'PlayerID':203083,'季节':'2015-16,'季节类型':'常规赛'})
2 print\u get.url
---->3(获得)提升(状态)
4_get.json()
/库/Python/2.7/site-packages/requests/models.pyc处于raise_for_状态(self)
849
850如果http_错误消息:
-->851引发HTTPError(http\u error\u msg,response=self)
852
853 def关闭(自):
HTTPError:400客户端错误:请求错误
但是,如果我在浏览器中转到url,它会工作。然后,当我在浏览器(iPython正在运行的Chrome)中手动访问URL后,返回到代码并再次运行它时,代码不会出错。但是,它可能会返回到在顺序执行中提高错误

这段代码已经为我工作了数百次,甚至数千次,没有任何问题。如何修复此错误


谢谢。

HTTPError:400客户端错误:错误请求表示您的请求有错误。我认为服务器可能会检查HTTP请求中的一些头,例如
用户代理

因此,我尝试将User Agent头设置为模仿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
#无用户代理
>>>_get=get('http://stats.nba.com/stats/playergamelog“,参数={'PlayerID':203082,'赛季':'2015-16,'赛季类型':'常规赛'})
>>>_get.raise_for_status()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“C:\Python27\lib\site packages\requests\models.py”,第840行,处于raise_for_状态
引发HTTPError(http\u error\u msg,response=self)
requests.exceptions.HTTPError:400客户端错误:url请求错误:http://stats.nba.com/stats/playergamelog?PlayerID=203082&Season=2015-16和季节类型=常规+季节
#这次,将用户代理设置为模拟桌面浏览器
>>>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“,参数={'PlayerID':203082,'季节':'2015-16,'季节类型':'Regular seasure'},headers=headers)
>>>_get.raise_for_status()
>>>
#无误
在浏览器中访问URL后,它可以工作的原因是缓存


根据Alastair McCormack的说法,
stats.nba.com
由Akamai CDN提供,因此缓存可能发生在边缘,根据查询字符串/URI而不是额外的标题“变化”。一旦对该URI做出了有效响应,它就会被服务于该客户端的CDN边缘节点缓存


所以,当您在浏览器中访问url后运行代码时,CDN将返回缓存的响应。在这种情况下,不会引发400个问题。

stats.nba.com
由Akamai CDN提供,因此缓存可能发生在边缘,通过查询字符串/URI而不是额外的标题“变化”。一旦对该URI做出了有效响应,它就会被服务于该客户端的CDN边缘节点缓存。看起来服务器需要设置桌面类型的用户代理才能做出有效响应,因此需要设置为可缓存项。好地方@AlastairMcCormack,我认为你对cachingI的看法是正确的。我认为我理解你所阐述的逻辑,但如果我不理解,从纯实际的角度来看,这是否意味着如果我指定了一个有效的用户代理,我就不应该再遇到这种缓存问题了?@Andino是的,如果用户代理有效,一切都应该正常。缺少用户代理是您的问题,服务器响应400。缓存只是让您的代码在访问浏览器中的url后无误地运行。因为CDN将返回结果
# 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