Первое я почти все оставлю как у вас что бы вашу логику не нарушать, внесу небольшие изменения.
def read_csv(filename): #зачем у вас в оригинале параметр data если вы его не используете логичнее передавать имя файла.
with open(filename, encoding='utf-8') as file:
reader = csv.reader(file)
data = list(reader)
return data
далее используем вашу функцию для чтения получаем вложенный список в ответ, а нам он не нужен вложенный нам обычный нужен по этому распрямляем его.
data = read_csv('urls.csv')
flat_list = [item for sublist in data for item in sublist]
далее по все видимости вы собираетесь использовать эти ссылки для парсинга
пишете функцию которая будет парсить проходитесь циклом по списку flat_list и передаете в функцию по одной ссылке и все. Ваша функция будет принимать параметр url, затем делать request, затем beatifulsoup будет парситьи отдавать результат. Сделайте функцию которая делает это все для одного url, потом циклом по списку внутри цикла вызывайте функцию с параметром url.
А теперь общие соображения.
Зачем csv? когда читаешь csv он возвращает список под каждую строку, с обычного txt, мы бы этого избежали, я бы использовал бы вообще для записи json. Где ключом было бы название товара, а значением ссылка. Потому что если что не будет работать, то будет известно какой товар не удается спарсить.
Нужно создавать log file и писать туда что отдал сервер при запросе и туда же писать различные исключения а то потом ума не дашь где ошибка.
В коде много лишнего, параметр data в обоих случаях нужно заменить на filename. И много других погрешностей.