TypeError:字符串索引必须是整数,为什么?

时间:2016-03-31 12:18:00

标签: python xml django

我有

  

TypeError:字符串索引必须是整数

使用这些代码,请帮我找一个bug,我不知道如何解决它

from xml.etree import cElementTree as ET
from collections import defaultdict
def etree_to_dict(t):
d = {t.tag: {} if t.attrib else None}
children = list(t)
if children:
  dd = defaultdict(list)
  for dc in map(etree_to_dict, children):
    for k, v in dc.items():
      dd[k].append(v)
      d = {t.tag: {k: v[0] if len(v) == 1 else v for k, v in dd.items()}}
      if t.attrib:
        d[t.tag].update(('@' + k, v) for k, v in t.attrib.items())
      if t.text:
        text = t.text.strip()
        if children or t.attrib:
          if text:
            d[t.tag]['#text'] = text
          else:
            d[t.tag] = text
          return d

我认为问题在这里

e = ET.parse('adversolutions.xml')
d = etree_to_dict(e.getroot())
products = d['yml_catalog']['shop5']

for p in products:
  product = Product()
  product.name = p['name']
  product.description = p['description']
  product.price = p['price']
  product.category = p['category']
  product.external_url = p['url']
  product.category_id = p['categoryId']
  product.currencies = p['currencies']

  product.save()

这一切都是为了反序列化xml并保存数据和模型django 所有追溯:

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/alexandr/beo/lib/python3.4/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  File "/home/alexandr/beo/lib/python3.4/site-packages/django/core/management/__init__.py", line 354, in execute
    django.setup()
  File "/home/alexandr/beo/lib/python3.4/site-packages/django/__init__.py", line 21, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/home/alexandr/beo/lib/python3.4/site-packages/django/apps/registry.py", line 108, in populate
    app_config.import_models(all_models)
  File "/home/alexandr/beo/lib/python3.4/site-packages/django/apps/config.py", line 202, in import_models
    self.models_module = import_module(models_module_name)
  File "/home/alexandr/beo/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1129, in _exec
  File "<frozen importlib._bootstrap>", line 1471, in exec_module
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "/home/alexandr/beo/posts/models.py", line 9, in <module>
    from products.models import Product
  File "/home/alexandr/beo/products/models.py", line 155, in <module>
    product.name = p['name']
TypeError: string indices must be integers

这条线全部工作

products = d['yml_catalog']['shop5']

问题从这里开始:

for p in products:
  product = Product()
  product.name = p['name']
  product.description = p['description']
  product.price = p['price']
  product.category = p['category']
  product.external_url = p['url']
  product.category_id = p['categoryId']
  product.currencies = p['currencies']

  product.save()

打印(产品): 和平的大型xml文件

'@available': 'true', 'param': {'@name': 'Размер', '@unit': 'INT', '#text': 'L'}, '@id': '117213', 'name': 'Штаны Pocket Grey', 'oldprice': '1990', '@group_id': '1172', 'description': None, 'picture': 'http:///upload/iblock/559/559b4fe1c3b397bf84eb16686bd5aadf.jpg', 'url': 'http:///catalog/shtany/galife_pocket_grey/', 'currencyId': 'RUB', 'price': '1990'}, {'vendor': 'Envy Lab', '@available': 'true', 'param': {'@name': 'Размер', '@unit': 'INT', '#text': 'S'}, '@id': '117511', 'name': 'Галифе Dark Black', 'oldprice': '1990', '@group_id': '1175', 'description': None, 'picture': 'http:///upload/iblock/11d/11d1c223f4e65b347cd5823fff9e5e9b.jpg', 'url': 'http:///catalog/shtany/galife_dark_black/', 'currencyId': 'RUB', 'price': '1990'}, {'vendor': 'Envy Lab', '@available': 'true', 'param': {'@name': 'Размер', '@unit': 'INT', '#text': 'M'}, '@id': '117512', 'name': 'Галифе Dark Black', 'oldprice': '1990', '@group_id': '1175', 'description': None, 'picture': 'http:///upload/iblock/11d/11d1c223f4e65b347cd5823fff9e5e9b.jpg', 'url': 'http:///catalog/shtany/galife_dark_black/', 'currencyId': 'RUB', 'price': '1990'}, {'vendor': 'Envy Lab', '@available': 'true', 'param': {'@name': 'Размер', '@unit': 'INT', '#text': 'L'}, '@id': '117513', 'name': 'Галифе Dark Black', 'oldprice': '1990', '@group_id': '1175', 'description': None, 'picture': 'http:///upload/iblock/11d/11d1c223f4e65b347cd5823fff9e5e9b.jpg', 'url': 'http:///catalog/shtany/galife_dark_black/', 'currencyId': 'RUB', 'price': '1990'}]}, 'url': 'http://www.envylab.ru', 'name': 'Envylab', 'categories': {'category': [{'#text': 'Поло', '@id': '61'}, {'#text': 'Толстовки', '@id': '65'}, {'#text': 'Штаны', '@id': '72'}, {'#text': 'Шапки', '@id': '74'}, {'#text': 'Рубашки', '@id': '76'}]}, 'company': 'Envylab'}

打印(P): 其中一个结果

categories

打印(类型(产品))

<class 'dict'>

1 个答案:

答案 0 :(得分:2)

你有一个描述

的追溯
product.name = p['name']
TypeError: string indices must be integers

这意味着显然p是一个字符串,而你正试图像字典一样使用它。

你是对的,这个问题出现在这里(虽然它可能来自你到达那里之前的问题):

products = d['yml_catalog']['shop5']

# Please add this print
print(products)
print(type(products))

for p in products:
    # Please add this print
    print(p)
    product = Product()
    product.name = p['name']
...

显然,您希望products成为词典列表,但是您会得到一个字符串列表。

应该很容易通过在循环之前打印products和/或在循环开始时p来验证。

print是一个非常简单的调试工具,非常适合这类问题。

修改

目前还不清楚products是什么。您也可以打印其类型(参见上面的编辑代码)。