Как исправить '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 шт):
Основная суть вашей ошибки: "Во время обработки исключения снова произошло исключение". И произошло оно вот здесь:
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 - это снова плохо, это дополнительный источник трудноуловимых взглядом ошибок.