【问题标题】:Beautifulsoup Parser Truncating larger jsonBeautifulsoup Parser 截断较大的 json
【发布时间】:2014-08-31 12:13:06
【问题描述】:

我正在尝试从网站上抓取一些 json 数据。我正在使用BeautifulSoup (bs4),如下面的代码所示

import re
import csv
import json
import urllib2
from bs4 import BeautifulSoup as BS

city = 'Helsinki';

csvFile = csv.writer(open( city + ".csv", "wb+"))
csvFile.writerow(["tempid","latitude", "longitude"])

pageID = 0

locPage = urllib2.urlopen("http://runkeeper.com/user/maxspowers79/route/2481336")
soup = BS(locPage, "lxml").findAll('script',{"src":False})
print soup
pageID += 1
print pageID
for s in soup:
    if 'routePoints' in s.string:
        value = "[{" + s.string.split("}];")[0].split("[{")[1] + "}]"
        #print value
        jsonObj = json.loads(value)
        for x in jsonObj:
            csvFile.writerow([pageID,x["latitude"],x["longitude"]])

例如,这是我测试过的随机城市和随机路线的 runkeeper 网站。该代码适用于其他类似页面,但对于像这样的较长路线(如果您在浏览器中查看源代码,则更大的 gps json)。

soup 变量被截断,正如您从发出的打印命令中看到的那样。因此,json 无效,我无法解析它。

我也尝试使用不同的解析器 (html5lib),但情况更糟。 soup 变量可以容纳多大的字符串有限制吗?

否则为什么会截断?

我该如何处理?

【问题讨论】:

  • 我已经使用包含 json 变量 routePoints 中的 9 万多个坐标的虚拟 runkeeper 页面测试了您的代码,它运行良好,解析良好,所有项目都保存在输出文件中。我想这不是 BeautifulSoup 问题,因为您的代码对我来说很好。
  • @AniversarioPeru 您是否尝试过我发布的这个特定的 runkeeper 页面?
  • 是的,并且该特定页面没有问题。这就是为什么我增加了数据量来看看它是否会失败。
  • 我还运行了@Vleseg 的代码并得到了相同的输出Helsinki.csv 文件(diff 命令显示它们是相同的)。
  • @AniversarioPeru 这确实很有趣。根据 Vleseg 所说,我的原始代码对他来说也遇到了同样的限制。一定有我遗漏的东西。

标签: python json web-scraping html-parsing beautifulsoup


【解决方案1】:

我测试了你的代码,看起来 - 是的 - BeautifulSoup 对标签内容有一些限制。

考虑改用简单直接的字符串操作:

import re
import csv
import json
import urllib2

city = 'Helsinki';

csvFile = csv.writer(open( city + ".csv", "wb+"))
csvFile.writerow(["tempid","latitude", "longitude"])

pageID = 0

locPage = urllib2.urlopen("http://runkeeper.com/user/maxspowers79/route/2481336")
content = locPage.read()

start_at_s, end_at_s = 'var routePoints = ', 'mapController.initialize'

start_at_p = content.index(start_at_s) + len(start_at_s)
end_at_p = content.index(end_at_s)
raw_json = content[start_at_p:end_at_p].strip().strip(';')

jsonObj = json.loads(raw_json)

pageID += 1
print pageID


for x in jsonObj:
    print x
    csvFile.writerow([pageID,x["latitude"],x["longitude"]])

【讨论】:

    【解决方案2】:

    尝试使用 lxml 重写您的代码。它应该比 beautifulsoup 更健壮

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-21
      • 2018-01-14
      相关资源
      最近更新 更多