Ошибка при сохранении в CSV

Не могу сохранить результаты в CSV, ошибка:

writer.writerow([item['Product'], item['Price']])
TypeError: list indices must be integers or slices, not str

Код:


    s = Service('C:/Users/user/Desktop/полезно/chromedriver.exe')
browser = webdriver.Chrome(service=s)
CSV = 'cards.csv'
URL = 'https://www.ozon.ru/category/mayonez-9286/?delivery=2'
HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/'
                         '100.0.4896.75 Safari/537.36',
           'accept': '*/*'}
def get_html(url, params=''):
    r = requests.get(url, headers=HEADERS, params=params)
    return r

webAdr = get_html(URL)
browser.get(webAdr.url)

# кликаем в ввод города
button = browser.find_element(By.XPATH, '//*[@id="layoutPage"]/div[1]/div[1]/div/div/button/span/span')
button.click()

# вводим город
city_inp = browser.find_element(By.CLASS_NAME, 'ui-h8')
city = "Санкт Петербург"
time.sleep(1)
city_inp.send_keys(city)
time.sleep(1)
city_list = browser.find_element(By.CLASS_NAME,'s4g')
city_inp.send_keys(Keys.ENTER)

# парсим
time.sleep(3)
#soup = BeautifulSoup(browser.page_source,'lxml')
#print(len(soup.find_all('div', class_='n9i')))

#html = browser.page_source
def get_content():
    soup = BeautifulSoup(browser.page_source,'lxml')
    items = soup.find_all('div', class_='oi0 i1o')
    cards = []

    for item in items:
        cards.append(
            {
                'Cat': soup.find('h1', class_='ip5').get_text(strip=True),
                'City': soup.find('span', class_='ui-f0').get_text(strip=True),
                'Product': item.find('span', class_='ed d0e e0d ed2 tsBodyL i5m').get_text(strip=True),
                'Price': item.find('div', class_='ui-s2').get_text(strip=True)
            }
        )
    return cards
#html = get_html(browser.current_url)
#print(get_content())

def save_doc(items, path):
    with open(path, 'w', encoding="utf-32", newline='') as file:
        writer = csv.writer(file, delimiter=';')
        writer.writerow(['Категория','Город','Продукт', 'Цена'])
        for item in items:
            writer.writerow([item['Cat'], item['City'], item['Product'], item['Price']])

def parser():
    ht = get_html(browser.current_url)
    if ht.status_code == 200:
        #cards = []
        cards = get_content()
        save_doc(cards, CSV)
    else:
        print('Error')

Ответы (2 шт):

Автор решения: gil9red

Ошибка означает, что у вашего списка было обращение к элементам через строку, а не индекс, т.е. в item у вас не словарь, а список:

writer.writerow([item['Product'], item['Price']])

TypeError: list indices must be integers or slices, not str

Пример получения этой ошибки:

item = ['123']
print(item['Product'])
# TypeError: list indices must be integers or slices, not str
→ Ссылка
Автор решения: CrazyElf
cards = []
cards.append(get_content())
save_doc(cards, CSV)

get_content возвращает список словарей, вы его вложили в другой список. save_doc ожидает список словарей, а не список словарей, вложенный в другой список первым элементом. Чинится это просто - передайте список как есть, без этих манипуляций:

cards = get_content()
save_doc(cards, CSV)

А если прямо очень хотите сделать новый список нужного формата, то используйте extend, а не append, тогда список словарей попадёт не весь сразу в один элемент нового списка, а распространится по новому списку и будет снова список словарей:

cards = []
cards.extend(get_content())
save_doc(cards, CSV)
→ Ссылка