【问题标题】:Downloading Json data from website从网站下载 Json 数据
【发布时间】:2018-05-19 08:17:16
【问题描述】:

我正在尝试编写一个 python 脚本,它一次接收一堆 url 并获取该 url 的响应内容并将其存储为 json 文件。

这是我最初为获取 url 的响应而写的内容

def download_json()

    params={'id':00163E0BD0C1FA89,
            'list':'141',
            'queue': 'gen',
            'type': 'abc_stat'
           }



    req_obj= requests.get(link, params=params)
    print(req_obj.url)
    print(req_obj.status_code)

    return req_obj

它会创建正确的 url,因为当我直接在浏览器中复制 url 时,它会以 json 格式显示输出。这是我在浏览器上看到的一行 json 输出:

{
  "DATA" : [
    {
      "SCHEMA" : "abc_4_QAATu2.",
      "ID" : "QAATu2",
      "IM_ID" : "22faba86_c9e0_4dbc",
      "S_NUMBER" : "502379284",
      "CONFIG_TYPE" : "las_home_type",
      "CONFIG_KEY" : "las_home_key",
      "CONFIG_LONG_V" : "1",
      "CONFIG_STRING_V" : "https://abc-deg/development",
      "MODIFIED_DATE" : "Unknown"
    },

所以这确实表明当我直接在浏览器中输入 url 时,数据以 json 格式返回。

但是我的请求对象有这个标题:

输出[26]:

{'content-length': '15457', 'expires': '0', 'content-encoding': 'gzip', 'cache-control': 'no-cache, no-store, private', 'set-cookie': 'login-XSRF_RZA=2018051-axJnifQUpOnrS8WCFI; path=/abc/deo/cpo; secure; HttpOnly, usercontext=client=002; path=/', 'content-type': 'text/html; charset=utf-8', 'pragma': 'no-cache, no-store, private'}

现在,当我执行 requests.json() 以获取 json python 对象中的数据时,出现以下错误

JSONDecodeError                           Traceback (most recent call last)
<ipython-input-28-4cfc1a694fcf> in <module>()
----> 1 req_obj.json()

/Users/anaconda/envs/dl/lib/python3.5/site-packages/requests/models.py in json(self, **kwargs)
    890                     # used.
    891                     pass
--> 892         return complexjson.loads(self.text, **kwargs)
    893 
    894     @property

/Users/anaconda/envs/dl/lib/python3.5/json/__init__.py in loads(s, encoding, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    317             parse_int is None and parse_float is None and
    318             parse_constant is None and object_pairs_hook is None and not kw):
--> 319         return _default_decoder.decode(s)
    320     if cls is None:
    321         cls = JSONDecoder

/Users/anaconda/envs/dl/lib/python3.5/json/decoder.py in decode(self, s, _w)
    337 
    338         """
--> 339         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    340         end = _w(s, end).end()
    341         if end != len(s):

/Users/anaconda/envs/dl/lib/python3.5/json/decoder.py in raw_decode(self, s, idx)
    355             obj, end = self.scan_once(s, idx)
    356         except StopIteration as err:
--> 357             raise JSONDecodeError("Expecting value", s, err.value) from None
    358         return obj, end

JSONDecodeError: Expecting value: line 2 column 1 (char 2)

编辑:

如果您在上面的标题中看到的 content_type 显示为 html,即使在浏览器上它显示 json 作为输出

但是当我这样做时

req_obj.json 

<bound method Response.json of <Response [200]>>

但是 req_obj.json() 给出以下错误。

知道为什么当输出实际上是如上所示的 json 格式时,它不能将数据转换为 json 格式吗?谢谢

【问题讨论】:

  • 如果您使用req_obj.text 而不是req_obj.json() 会发生什么?它输出什么?
  • 我得到了 html 输出。我不确定为什么在浏览器上我得到 json 输出时它给我 html 输出,如图所示。虽然在标题中 content_type 被提及为 html。我该如何改变呢?

标签: python json


【解决方案1】:

根据documentation

如果 JSON 解码失败,r.json() 会引发异常。为了 例如,如果响应得到 204(无内容),或者如果响应 包含无效 JSON,尝试 r.json() 引发 ValueError: No JSON object could be decoded.

虽然它没有抛出相同的错误消息,但原因似乎是相同的:您可能没有得到 JSON 作为答案,这可以解释为什么 JSONDecode 会抛出异常。

您应该能够通过打印req_obj.text 而不是使用req_obj.json() 来确认这一点。

至于如何解决,我怀疑您使用浏览器发出的请求与您使用Python发出的请求之间一定存在差异(例如不同的参数)。

我建议您阅读this 以进一步调查问题的根源。

【讨论】:

  • req_obj.text 给了我整个 html 源代码。所以它正在工作。此外,当我执行 req_obj.json 而不是 req_obj.json() 时,它会打印 >
  • 我向浏览器发出的请求使用我使用 python 脚本创建的相同 url。查看我的代码中打印 url 的 print(url),然后我使用该 url 粘贴到浏览器中。所以它具有相同参数的相同网址
  • 如果您看到的是 HTML 而不是 json,它将无法正常工作。这就是req_obj.json() 抛出异常的原因,请求返回的是 HTML 而不是您期望的 JSON。
  • 这就是我无法理解的。为什么它会在浏览器中抛出 json 呢?我粘贴在我的问题中的输出是 json 输出。两者都是同一个链接
  • 您在浏览器上发出的请求与您使用 Python 发出的请求之间必须有所不同。您是否尝试过直接使用带有参数的完整网址?例如req_obj = requests.get('your/site/url?id=00163E0BD0C1FA89&amp;list=141&amp;queue=gen&amp;type=abc_stat');
【解决方案2】:

根据本文档:http://docs.python-requests.org/en/master/

您可以查看req_obj.status_coder.headers['content-type']。如果 status_code 是 200 并且内容类型是 'application/json; charset=utf8' 那么你可以尝试检查 req_obj.json()

【讨论】:

  • Status_code 是 200。但是 content_type 是 html。我不知道为什么。在浏览器上,它会在我上面粘贴的 json 中抛出输出。此外,当我执行 req_obj.json (不带括号)时,它确实给了我 200 个代码。 >的
  • 如果标头接受的是 json,则有一些网站返回 json。你可以试试:requests.get(url, headers={'accept': 'application/json'})
猜你喜欢
相关资源
最近更新 更多
热门标签