使用 urllib.URLopener 获取 JSON 时出现问题

Problems getting JSON with urllib.URLopener

我在使用 urllib.URLopener 获取 JSON 时遇到问题,即使我可以在导航器中看到它。

代码:

import urllib
import json
json_obj = urllib.URLopener()
json_obj.retrieve(json_adress, self.home + "/.cache/program/file.json")

错误:

('http error', 404, 'Not Found', <httplib.HTTPMessage instance at 0x7fa73d9b3a28>)

5分钟后我可以得到它,但是另一个地址失败了。发生了什么事?

例如JSON文件的URL是:

http://webservices.francetelevisions.fr/tools/getInfosOeuvre/v2/?idDiffusion=135842229&catalogue=Pluzz&callback=webserviceCallback_135842229

您尝试访问的 URL 托管在 CDN 上,并非所有服务器似乎都有您请求的内容:

$ host webservices.francetelevisions.fr
webservices.francetelevisions.fr is an alias for www-es.francetelevisions.fr.
www-es.francetelevisions.fr is an alias for francetv.fr.edgesuite.net.
francetv.fr.edgesuite.net is an alias for a253.w5.akamai.net.
a253.w5.akamai.net has address 23.3.13.170
a253.w5.akamai.net has address 23.3.13.176

查找主机名时您的计算机的确切地址取决于您的地理位置;通过解析 DNS 别名,DNS 服务器使用您的 IP 地址来猜测网络中哪个服务器可能离您更近。

很可能更新会逐渐推出到 CDN 机器,或者在第一次 DNS 查找过期后,您会获得一个不同的 IP 地址以便稍后联系。无论哪种方式,您都无能为力 Python;除非您知道原始服务器(网站通常 不会 公开以避免超载),否则您必须遵循正常的 CDN 更新流程。

我终于通过添加 header 来分叉 Firefox 找到了解决方案:

json_obj = urllib.URLopener()
json_obj.addheaders = [("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:44.0) Gecko/20100101 Firefox/44.0")]
json_obj.retrieve(json_adress, self.home + "/.cache/program/file.json")

现在每次都有效!