Проблема с кодировкой сохранения в CSV

Запускаю парсер на 10 страниц, до 8 всё идёт хорошо, потом ошибка

    Traceback (most recent call last):
      File "D:\Python\QuotesToScrape.py", line 55, in <module>
        parser()
      File "D:\Python\QuotesToScrape.py", line 51, in parser
        save_doc(cards, CSV)
      File "D:\Python\QuotesToScrape.py", line 35, in save_doc
        writer.writerow([item['title']])
      File "C:\Users\100nout.by\AppData\Local\Programs\Python\Python39\lib\encodings\cp1251.py", line 19, in encode
        return codecs.charmap_encode(input,self.errors,encoding_table)[0]
    UnicodeEncodeError: 'charmap' codec can't encode character '\u2032' in position 1: character maps to <undefined>

Process finished with exit code 1

Как я понимаю проблема в апострофе после которого сразу идёт пробел на странице https://quotes.toscrape.com/page/8/ и эксель если ввести вручную "' "(знак ' и пробел) не отображает их. Если применять кодировку utf-8 то всё двойные ковычки в цитатах становятся иероглифами. Хелп плиз

import requests
from bs4 import BeautifulSoup
import csv

CSV = 'cards.csv'
HOST = 'https://quotes.toscrape.com/'
URL = 'https://quotes.toscrape.com/page/'
HEADERS = {
    'accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
}

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

def get_content(html):
    soup = BeautifulSoup(html, 'html.parser')
    items = soup.find_all('div', class_ = 'quote')
    cards = []
    for item in items:
        cards.append(
            {
                'title' : item.find('span', class_ = 'text').get_text()
            }
        )
    return cards

def save_doc(items, path):
    with open(path, 'w', newline='') as file:
        writer = csv.writer(file, delimiter = ';')
        writer.writerow(['Название'])
        for item in items:
            writer.writerow([item['title']])

def parser():
    PAGENATION = input('Укажите количество страниц для парсинга: ')
    PAGENATION = int(PAGENATION.strip())
    if PAGENATION > 10:
        print(f'Максимальное количество страниц для парсинга - 10.')
    else:
        html = get_html(HOST)
        if html.status_code == 200:
            cards = []

            for page in range(1, PAGENATION + 1):
                print(f'Парсим страницу: {page}')
                html = get_html(URL + str(page))
                cards.extend(get_content(html.text))
                save_doc(cards, CSV)
        else:
            print('Error')

parser()

Бонусный вопрос не по теме: Может посоветуете где можно изучить материалы по теме парсинга при скроле с подгрузкой и парсинга по страницам если нет параметра page, т.е. адрес каждой страницы состоит из набора символов? Благодарю.


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

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

При записи файла в кодировке cp1251 (родная кодировка Windows и Excel) не удаётся преобразовать unicode символ в эту кодировку. Как вариант, могу предложить заменять этот символ на обычный апостроф:

writer.writerow([item['title'].replace('\u2032',"'")])

Ну или найдите в кодировке cp1251 подходящий символ и делайте замену на него.

Вероятно, есть и другие решения, но это работает.

→ Ссылка