Текст в csv отображается символами

При парсинге сайта print выводит весь текст в читаемом виде, а при записи в csv, весь не английский текст в виде символов

import requests
from bs4 import BeautifulSoup
import csv

headers = {
  'Host': 'work.ua',
  'User-Agent': 'Safari',
  'Accept': '*/*',
  'Accept-Encoding': 'gzip, deflate, br',
  'Connection': 'keep-alive'
}

URL_work_ua = "https://www.work.ua"

def extract_job_work_ua(html):
    title = html.find('a').text
    company = html.find('div', {'class': 'add-top-xs'}).find('b').text
    company = company.strip()
    city = html.find('div', {'class': 'add-top-xs'}).find_all('span')
    if city[len(city)-2].text == '·':
        location = city[len(city)-1].text
    if city[len(city)-2].text != '·':
        location = city[len(city)-4].text
    link = URL_work_ua + html.find('a')['href']
    # print({'title': title, 'company': company, 'location': location, "link": link})
    return {'title': title, 'company': company, 'location': location, "link": link}

def extract_workUA_jobs():
    jobs = []
    for page in range(1):
        result = requests.get(f'{URL_work_ua}{"/jobs/?ss="}{page}', headers)
        soup = BeautifulSoup(result.text, "html.parser")
        results = soup.find_all('div', {'class': 'card card-hover card-visited wordwrap job-link js-hot-block'})
        for result in results:
            job = extract_job_work_ua(result)
            jobs.append(job)
    return jobs

def save_to_csv(jobs):
        for i in range(len(jobs)):
            with open('test.csv', "a", newline="") as file:
                print(jobs[i])
                # title = jobs[i]['title']
                title = jobs[i].values()
                writer = csv.writer(file)
                writer.writerow(title)

jobs = extract_workUA_jobs()
save_to_csv(jobs)

В csv получается текст типа:

����������� ��������

Если добавить при открытии файла csv в качестве параметра encoding, в текст не преобразуется:

with open('test.csv', "a", newline="", encoding='utf8') as file:

Перебрал много кодировок, но ничего не помогло


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

Автор решения: Namerek
def save_to_csv(jobs):
        for i in range(len(jobs)):
            with open('test.csv', "a", newline="", encoding='utf-8-sig') as file:
                                    #                        ^^^^^^^^^
                print(jobs[i])
                # title = jobs[i]['title']
                title = jobs[i].values()
                writer = csv.writer(file)
                writer.writerow(title)

И еще

soup = BeautifulSoup(result.content, "html.parser")
#                           ^^^^^^^

Зашло как-то под настроение (небольшая оптимизация):

import csv

import requests
from bs4 import BeautifulSoup

headers = {
    'Host': 'work.ua',
    'User-Agent': 'Safari',
    'Accept': '*/*',
    'Accept-Encoding': 'gzip, deflate, br',
    'Connection': 'keep-alive'
}

URL_work_ua = "https://www.work.ua"

csv_header = ['title', 'company', 'location', "link"]


def extract_job_work_ua(html):
    title = html.find('a').text
    company = html.find('div', {'class': 'add-top-xs'}).find('b').text
    company = company.strip()
    city = html.find('div', {'class': 'add-top-xs'}).find_all('span')

    location = None

    if city[len(city) - 2].text == '·':
        location = city[len(city) - 1].text
    if city[len(city) - 2].text != '·':
        location = city[len(city) - 4].text
    link = URL_work_ua + html.find('a')['href']

    return dict(zip(csv_header, [title, company, location, link]))


def extract_workUA_jobs():
    data = []
    for page in range(1):
        result = requests.get(f'{URL_work_ua}{"/jobs/?ss="}{page}', headers)
        soup = BeautifulSoup(result.content, "html.parser")
        data += map(
            extract_job_work_ua,
            soup.find_all(
                'div',
                # {'class': 'card card-hover card-visited wordwrap job-link js-hot-block'}
                class_='card-hover'
            )
        )
    return data


with open('test.csv', "w", newline="", encoding='utf-8-sig') as file:
    writer = csv.DictWriter(file, fieldnames=csv_header, dialect=csv.unix_dialect, delimiter=",")
    writer.writeheader()
    writer.writerows(extract_workUA_jobs())

С самим парсингом тоже можно поколдовать но не сейчас.
Получившийся csv можно смело открывать в Excel

Можно так-же вывести в красивую таблицу с библиотекой tabulate

tab_header = {'title': 'Вакансія', 'company': 'Компанія', 'location': 'Місто', 'link': 'Посилання'}

obj = extract_workUA_jobs()

print(tabulate(
    obj,
    headers=tab_header,
    tablefmt='pipe'
))
Вакансія Компанія Місто Посилання
Переводчик в брачное агентство Campus Київ https://www.work.ua/jobs/4749450/
Барбер у Ужгород Gentlemens Club, barbershop Ужгород, шукаємо у Львові https://www.work.ua/jobs/4792819/
Call-Center Operator (Delivery) Дi енд Зi Нетворкс Лiмiтед, ТОВ Львів https://www.work.ua/jobs/4788419/
Logistics Dispatcher Вайз Консалтинг Львів https://www.work.ua/jobs/4505532/
Call-Center Operator (Surveys) Дi енд Зi Нетворкс Лiмiтед, ТОВ Львів https://www.work.ua/jobs/4797498/
Інженер-механік (с. Новоставці) МХП, агроіндустріальний холдинг Теофіполь https://www.work.ua/jobs/4795354/
Диспетчер в офіс служби "Таксі 838" Такси 838 Львів https://www.work.ua/jobs/4790251/
SMM-менеджер Irens Одеса https://www.work.ua/jobs/4797776/
Водитель на новые авто компании (Uklon, Bolt, Uber, 838) Озон, СК, ТОВ Львів https://www.work.ua/jobs/4617525/
Диспетчер в офіс служби "Таксі 838" Такси 838 Одеса https://www.work.ua/jobs/4790253/
Комплектовщик в Вышгород Бизнес Груп Вишгород, шукаємо у Сумах https://www.work.ua/jobs/3981474/
Технолог м'ясоковбасного виробництва Ратушняк В.В., ФОП Тернопіль https://www.work.ua/jobs/4793031/
Оператор чата, переводчик английского языка в брачное агентство Alexis Київ https://www.work.ua/jobs/4793344/
CRM-manager Softum Київ https://www.work.ua/jobs/4792303/
→ Ссылка