1

我正在尝试从使用 javascripts 加载数据的网站获取有关设备的定价信息。我正在 JSON 字典结构中获取数据。下面是我正在使用的代码:

# -*- coding: cp1252 -*-
import csv
import urllib2
import sys
import time
import re
import json
from bs4 import BeautifulSoup
from itertools import islice
from pprint import pprint

page = urllib2.urlopen('http://www.vodafone.de/privat/tarife/red-smartphone-tarife.html').read()
soup = BeautifulSoup(page)
x = [None]*1000

i = 0
j = 0
k = 0
scripts = soup.find_all('script')
script = next(s.text for s in scripts if s.string and 'window.rates' in s.string)
datastring = script.split('phones=')[1].split(';window.')[0]
datastring = re.sub(ur'([{,])([a-z]\w*):', ur'\1"\2":', datastring)
data = json.loads(datastring)

for d in data:
    for j in data[d]:
        pprint(data[d]['name']) 
        x[i] = data[d]['name']
        i = i + 1

这部分为我提供了网页中的设备列表。

但是,当我使用相同的方法获取 JSON 数据字典中的更高级别的定价信息(如下所述)时,我得到TypeError: string indices must be integers-

for d in data:
    for j in data[d]:
        for k in data[d][j]:
            pprint(data[d][j][k]) 
            x[i] = data[d][j][k]
            i = i + 1

这是我正在抓取的 JSON 数据结构片段,我需要从中提取信息:

{u'deliveryTime': u'Lieferbar innerhalb 48 Stunden',
 u'image': u'/images/m707491_300465.jpg',
 u'name': u'BlackBerry Bold 9900',
 u'sku1104261': {u'e': u'169.90', u'p': u'prod974431'},
 u'sku1444275': {u'e': u'129.90', u'p': u'prod974431'},
 u'sku1444283': {u'e': u'89.90', u'p': u'prod974431'},
 u'sku1444286': {u'e': u'49.90', u'p': u'prod974431'},
 u'sku1444291': {u'e': u'49.90', u'p': u'prod974431'}}
{u'deliveryTime': u'Vorauss. verfügbar ab Mitte Januar',
 u'image': u'/images/m1327474_300658.jpg',
 u'name': u'HTC One X+ mit limitiertem Beats-Headset',
 u'sku1444277': {u'e': u'249.90', u'p': u'prod1624433'},
 u'sku1444285': {u'e': u'119.90', u'p': u'prod1624433'},
 u'sku1444287': {u'e': u'99.90', u'p': u'prod1624433'},
 u'sku1444292': {u'e': u'99.90', u'p': u'prod1624433'},
 u'sku1474223': {u'e': u'399.90', u'p': u'prod1624433'}}

请帮我解决这个问题。

4

1 回答 1

1

根据您发布的 JSON 结构,它应该是这样的:

price = 0
for key, value in data.items():
    if key.startswith(u'sku') and isinstance(value, dict): 
        price += value.get(u'e', 0)

实际上,这里有几个基本概念:

  • 验证您是否需要密钥(跳过不以“sku”开头的密钥)
  • 验证子键是字典
  • 对 dicts使用.get()方法而不是直接引用。此方法允许您指定如果 dict 中没有这样的键将返回的默认值(并且不会引发异常)
于 2013-01-09T16:11:06.733 回答