Как исправить 'TypeError: string indices must be integers During handling of the above exception, another exception occurred:'

Пишу парсер для Яндекс.Дзен. Примерно через 3к полученных ссылок выскакивает ошибка 'TypeError: string indices must be integers During handling of the above exception, another exception occurred:'. В коде много неточностей и лишнего. Тут ещё сохраняются аккаунты только с ссылкой на ВК введите сюда описание изображения

import requests
from bs4 import BeautifulSoup
import csv
import os

URL = "https://zen.yandex.ru/media/zen/channels"



HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0', 'accept': '*/*'}
HOST = 'https://zen.yandex.ru'
FILE = 'log.csv'
linksa = []
links = ''
def get_html(url, params=None):
    r = requests.get(url, headers=HEADERS, params=params)
    return r

def get_pages_count(html):
    global num
    global URL
    soup = BeautifulSoup(html,'html.parser')
    pagination = soup.find_all('a',class_='pagination-prev-next__link')
    if pagination:
        URL = HOST + str(pagination[-1].get('href'))
        parser()
    else:
        return 'Пиздец'
    print(URL)
def get_content(html):
    global links
    soup = BeautifulSoup(html,'html.parser')
    items = soup.find_all('div',class_ = 'channel-item')
    for item in items:
        links = HOST + item.find('a', class_='channel-item__link').get('href')
        parser_links(links)

    get_pages_count(html)
def save_file(items, path):
    with open(path, 'w', newline='',encoding='utf-8') as file:
        writer = csv.writer(file, delimiter=';')
        writer.writerow(['Название', 'Ссылка', 'Контакт','Кол-во пользователей','Аудитория'])
        for item in items:
            writer.writerow([str(item['name']), str(item['link']), str(item['contact']),str(item['subs']),str(item['auditoria'])])
def get_content_links(html):
    soup = BeautifulSoup(html,'html.parser')
    items = soup.find_all('div',class_ = 'content')
    for item in items:
        try:
            contact = item.find('a', class_='desktop-channel-2-social-links__item').get('href')
            if 'https://vk.com' in contact:

                linksa.append({
                    'link':links ,
                    'name': item.find('div', class_='desktop-channel-2-top').get_text(),
                    'contact': item.find('a', class_='desktop-channel-2-social-links__item').get('href'),
                    'subs':  item.find('div', class_='desktop-channel-2-counter__value').get_text(),
                    'auditoria': item.find('div', class_='desktop-channel-2-bottom-layout__counter-container _is-last').get_text()
                    })
            else:
                return 1
        except Exception:
            return 'Херня'
    print(len(linksa))

def parser_links(links):
    try:
        global html
        html = get_html(links)
        print(links)

        if html.status_code == 200:
            get_content_links(html.text)
        else:
            print('Error')
    except Exception as e:
        print('Файл')

def parser():
    try:
        global html
        html = get_html(URL)
        if html.status_code == 200:
            print('Сохранение')
            save_file(linksa,FILE)

            get_content(html.text)
        else:
            print('Error')
    except Exception as e:
        print('Файл сохранён')
        save_file(links,FILE)


parser()

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

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

Основная суть вашей ошибки: "Во время обработки исключения снова произошло исключение". И произошло оно вот здесь:

except Exception as e:
    print('Файл сохранён')
    save_file(links,FILE)
              ^^^^^

Ошибка, которая произошла внутри обработки исключения: "TypeError: string indices must be integers" выходит потому, что в links у вас строка, а функция save_file ждёт на вход список, каждый элемент которого - словарь (как выше по коду, где save_file вызывается с другим параметром linksa).

И в целом это какая-то странная конструкция - вы считаете, что если произошло исключение, то всё прошло отлично ("Файл сохранён")? И ещё и снова вызываете в этом случае (причём с неправильным аргументом) ту функцию, которая, возможно и вызвала это исключение выше в блоке try/except? Не делайте так. Исключение - это исключение. Максимум что должно быть в блоке обработки исключения - печать ошибки или вывод ошибки в лог. Сложных каких-то действий, которые могут снова выбросить исключение там быть не должно (поймать это исключение будет уже некому).

И подумайте ещё над названиями переменных. Переменная с окончанием во множественном числе links, хранящая в себе один объект (строку) - это плохо (противоречит ожиданиям того, кто смотрит этот код). Две переменные с очень похожими названиями links и linksa - это снова плохо, это дополнительный источник трудноуловимых взглядом ошибок.

→ Ссылка