【问题标题】:Scraping JSON data from interactive chart - Extra data error `json.load()`从交互式图表中抓取 JSON 数据 - 额外数据错误 `json.load()`
【发布时间】:2021-03-22 16:20:49
【问题描述】:

我一直试图弄清楚如何使用这篇文章作为参考来抓取网络数据:How to scrape json data from an interactive chart?

我已从网站获得 JSON 图表数据,但在最后一步使用 json.load() 加载文件时遇到了困难。我不断收到错误消息:JSONDecodeError: Extra data: line 1 column 67193 (char 67192)

任何建议或帮助将不胜感激。

    import requests
    import json
    import codecs
    from pandas.io.json import json_normalize
    from bs4 import BeautifulSoup
    
    url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQaftrT4JJh6dqfFHaUuxiOE5CiFDTt2YIbiJe9sATHQrBILnfUVpSnDTKg26yTgmZKci4NVxtsByD7/pubchart?oid=1258306542&format=interactive"
    response = requests.get(url, verify=False)
    soup = BeautifulSoup(response.text, features="html.parser")
    scripts = soup.find_all('script')[1]
    
    for script in scripts:
        if 'chartJson' in script:
            encoded_string = script
            encoded_string = encoded_string.split("'chartJson': '",1)[-1]
            encoded_string = encoded_string.split("', 'fallbackUri'",1)[0]
            jsonStr = codecs.getdecoder('unicode-escape')(encoded_string)[0]
            jsonStr = jsonStr.split(',\\"parsedNumHeaders\\":1',1)[0]
            jsonStr = jsonStr.split('"rows":',1)[1]
            jsonObj = json.loads(jsonStr)

【问题讨论】:

  • 数据似乎不是有效的 JSON。该错误表明在字符 67192 之前存在有效的 JSON。请检查那里的响应!
  • 我将如何找出哪个字符是给我错误的字符? 67,000 个字符很多,TraceBack 也不会告诉您是哪个字符。

标签: python json web-scraping beautifulsoup


【解决方案1】:

您可以将jsonStr 粘贴到here 以查找问题。这段代码对我有用。您在 "rows" 键上进行了拆分,但该级别中还有另一个 "cols" 键。然后它们在末尾也是一个额外的逗号。

jsonStr = codecs.getdecoder('unicode-escape')(encoded_string)[0] 也没有处理 unicode 转义,所以我添加了jsonStr = jsonStr.encode('utf8').decode('unicode_escape')

import requests
import json
import codecs
from pandas.io.json import json_normalize
from bs4 import BeautifulSoup

import unicodedata

url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQaftrT4JJh6dqfFHaUuxiOE5CiFDTt2YIbiJe9sATHQrBILnfUVpSnDTKg26yTgmZKci4NVxtsByD7/pubchart?oid=1258306542&format=interactive"
response = requests.get(url, verify=False)
soup = BeautifulSoup(response.text, features="html.parser")
scripts = soup.find_all('script')[1]

for script in scripts:
    if 'chartJson' in script:
        encoded_string = script
        encoded_string = encoded_string.split("'chartJson': '",1)[-1]
        encoded_string = encoded_string.split("', 'fallbackUri'",1)[0]
        jsonStr = codecs.getdecoder('unicode-escape')(encoded_string)[0]
        jsonStr = jsonStr.split(',\\"parsedNumHeaders\\":1',1)[0]
        jsonStr = jsonStr.split('"rows":',1)[1]
        jsonStr = jsonStr.split('"cols":',1)[0].rstrip(',')
        jsonStr = jsonStr.encode('utf8').decode('unicode_escape')
        jsonObj = json.loads(jsonStr)

【讨论】:

  • 非常感谢!这是我第一次尝试网络爬虫,你的代码很容易理解,所以谢谢。
  • 网页抓取很有趣。它们并不像这些在脚本中嵌入 json 那样棘手(我讨厌那些!!)
猜你喜欢
  • 1970-01-01
  • 2014-06-08
  • 2021-04-05
  • 2015-08-12
  • 1970-01-01
相关资源
最近更新 更多