UnicodeEncodeError: 'charmap' codec can't encode character... при записи в csv

Делал парсер на питоне по инструкции, так сказать. Возникает ошибка (картинка), и не понимаю как ее решить. Код автора работает, но мой аналогичный - нет.

Я полагаю не хватает какого-то значения для юникода, но даже не знаю, как задать вопрос гуглу. Ошибка

Мой код:

import requests
from bs4 import BeautifulSoup
import csv
import os


URL = 'https://www.avito.ru/gelendzhik/kvartiry/sdam/na_dlitelnyy_srok-ASgBAgICAkSSA8gQ8AeQUg' # Cылка что парсим
HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36', 'accept': '*/*'}
HOST = 'https://www.avito.ru' # Используем если ссылка на обьявление хитрая и без этого начала
FILE = 'House.csv' # Имя файла

def get_html(url, params = None):
    r = requests.get(url, headers = HEADERS, params = params)
    return r

## Получаем колво страниц ##
def get_pages_count(html):
    soup = BeautifulSoup(html, 'html.parser')
    pageinate = soup.find_all('span', class_ = 'pagination-item-1WyVp') # Передаем блок со стрелками и нумерацией страниц
    if pageinate:
        return int(pageinate[-2].get_text()) # Здесь указываем последнюю стр. (должно быть -1, но у нас последний элемент стрелка)
    else:
        return 1

## Записываем контент ##
def get_content(html):
    soup = BeautifulSoup(html, 'html.parser') # Передаем страницу и указываем что работаем с html
    items = soup.findAll('div', class_ = 'item-with-contact') # Выбираем контейнер в котором лежит искомы обьект. Одна ячейка списка целиком
    hause = [] # Пустой словарь для найденного

    for item in items:
        hause.append({# Добавляем в наш слорь обьекты
            'title' : item.find('a', class_ = 'snippet-link').get_text(strip = True),
            'link' : HOST + item.find('a', class_ = 'snippet-link').get('href'),
            'price' : item.find('span', class_ = 'snippet-price').get_text(strip = True),
            'ulica' : item.find('span', class_ = 'item-address__string').get_text(strip = True),
        })
    return hause
# 'link' : HOST + item.find('a', class_ = 'ListingItemTitle-module__link').get('href'), / .find_next('span') Аналогичный поиск дальше

## Сохранение ##
def save_file(items, path): # Что сохраняем , куда
    with open(path, 'w', newline='') as file:
        writer = csv.writer(file, delimiter=';') # Указываем таблицу
        writer.writerow(['Обьявление', 'Ссылка', 'Цена', 'Адрес']) # Указываем титульные столбцы
        for item in items:
            writer.writerow([item['title'], item['link'], item['price'], item['ulica']])

## Сам парсер ##
def parse():
#    URL = input('Введите URL: ')
#    URL = URL.strip()
    html = get_html(URL)
    if html.status_code == 200: # Статус 200 - сайт отвечает
        house = []
        pages_count = get_pages_count(html.text)
        for page in range(1, pages_count + 1):
            print(f'Парсинг страницы {page} из {pages_count}')
            html = get_html(URL, params={'p' : page}) # Передаем страницу (в ключе указываем то как указывается страница на сайте)
            house.extend(get_content(html.text)) # Заносим данные в список
        save_file(house, FILE)
        print (f'Получено {len(house)} обьявлений')
        os.startfile(FILE)
    else:
        print('Ошибка URL \ Сайт не отвечает')


parse()


# аналогично парсингу каждой страницы сделать парсинг описания и телефона

Оригинальный код:

import requests
from bs4 import BeautifulSoup
import csv
import os

URL = 'https://auto.ria.com/newauto/marka-jeep/'
HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0', 'accept': '*/*'}
HOST = 'https://auto.ria.com'
FILE = 'cars.csv'


def get_html(url, params=None):
    r = requests.get(url, headers=HEADERS, params=params)
    return r


def get_pages_count(html):
    soup = BeautifulSoup(html, 'html.parser')
    pagination = soup.find_all('span', class_='mhide')
    if pagination:
        return int(pagination[-1].get_text())
    else:
        return 1


def get_content(html):
    soup = BeautifulSoup(html, 'html.parser')
    items = soup.find_all('div', class_='proposition_area')

    cars = []
    for item in items:
        uah_price = item.find('span', class_='size13')
        if uah_price:
            uah_price = uah_price.get_text().replace(' • ', '')
        else:
            uah_price = 'Цену уточняйте'
        cars.append({
            'title': item.find('h3', class_='proposition_name').get_text(strip=True),
            'link': HOST + item.find('h3', class_='proposition_name').find_next('a').get('href'),
            'usd_price': item.find('span', class_='size18').get_text(),
            'uah_price': uah_price,
        })
    return cars


def save_file(items, path):
    with open(path, 'w', newline='') as file:
        writer = csv.writer(file, delimiter=';')
        writer.writerow(['Марка', 'Ссылка', 'Цена в $', 'Цена в UAH'])
        for item in items:
            writer.writerow([item['title'], item['link'], item['usd_price'], item['uah_price']])


def parse():
#    URL = input('Введите URL: ')
#    URL = URL.strip()
    html = get_html(URL)
    if html.status_code == 200:
        cars = []
        pages_count = get_pages_count(html.text)
        for page in range(1, pages_count + 1):
            print(f'Парсинг страницы {page} из {pages_count}...')
            html = get_html(URL, params={'page': page})
            cars.extend(get_content(html.text))
        save_file(cars, FILE)
        print(f'Получено {len(cars)} автомобилей')
        os.startfile(FILE)
    else:
        print('Error')


parse()

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