Как исправить: «UnicodeDecodeError: кодек« ascii »не может декодировать байт»


459
as3:~/ngokevin-site# nano content/blog/20140114_test-chinese.mkd
as3:~/ngokevin-site# wok
Traceback (most recent call last):
File "/usr/local/bin/wok", line 4, in
Engine()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 104, in init
self.load_pages()
File "/usr/local/lib/python2.7/site-packages/wok/engine.py", line 238, in load_pages
p = Page.from_file(os.path.join(root, f), self.options, self, renderer)
File "/usr/local/lib/python2.7/site-packages/wok/page.py", line 111, in from_file
page.meta['content'] = page.renderer.render(page.original)
File "/usr/local/lib/python2.7/site-packages/wok/renderers.py", line 46, in render
return markdown(plain, Markdown.plugins)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 419, in markdown
return md.convert(text)
File "/usr/local/lib/python2.7/site-packages/markdown/init.py", line 281, in convert
source = unicode(source)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 1: ordinal not in range(128). -- Note: Markdown only accepts unicode input!

Как это исправить?

В некоторых других статических приложениях для блогов на Python публикация на китайском языке может быть успешно опубликована. Например, это приложение: http://github.com/vrypan/bucket3 . На моем сайте http://bc3.brite.biz/ китайская почта может быть успешно опубликована.


Ответы:


569

tl; dr / quick fix

  • Не декодировать / кодировать Вилли Нилли
  • Не думайте, что ваши строки в кодировке UTF-8
  • Попробуйте преобразовать строки в строки Unicode как можно скорее в вашем коде
  • Исправьте вашу локаль: как решить UnicodeDecodeError в Python 3.6?
  • Не поддавайтесь искушению использовать быстрые reloadхаки

Unicode Zen в Python 2.x - длинная версия

Не видя источника, трудно понять причину, поэтому мне придется говорить в целом.

UnicodeDecodeError: 'ascii' codec can't decode byteОбычно это происходит, когда вы пытаетесь преобразовать Python 2.x, strкоторый не поддерживает ASCII, в строку Unicode без указания кодировки исходной строки.

Вкратце, строки Unicode - это совершенно отдельный тип строки Python, который не содержит никакой кодировки. Они содержат только коды точек Unicode и поэтому могут содержать любую точку Unicode по всему спектру. Строки содержат кодированный текст, beit UTF-8, UTF-16, ISO-8895-1, GBK, Big5 и т. Д. Строки декодируются в Unicode, а Unicodes - в строки . Файлы и текстовые данные всегда передаются в закодированных строках.

Авторы модуля Markdown, вероятно, используют unicode()(там, где выбрасывается исключение) в качестве качественного шлюза для остальной части кода - он преобразует ASCII или переупорядочивает существующие строки Unicodes в новую строку Unicode. Авторы Markdown не могут знать кодировку входящей строки, поэтому будут полагаться на то, что вы декодируете строки в строки Unicode, прежде чем переходить к Markdown.

Строки Unicode могут быть объявлены в вашем коде, используя uпрефикс к строкам. Например

>>> my_u = u'my ünicôdé strįng'
>>> type(my_u)
<type 'unicode'>

Строки Unicode могут также поступать из файлов, баз данных и сетевых модулей. Когда это происходит, вам не нужно беспокоиться о кодировке.

Gotchas

Преобразование из strв Unicode может произойти, даже если вы не вызываете явно unicode().

Следующие сценарии вызывают UnicodeDecodeErrorисключения:

# Explicit conversion without encoding
unicode('€')

# New style format string into Unicode string
# Python will try to convert value string to Unicode first
u"The currency is: {}".format('€')

# Old style format string into Unicode string
# Python will try to convert value string to Unicode first
u'The currency is: %s' % '€'

# Append string to Unicode
# Python will try to convert string to Unicode first
u'The currency is: ' + '€'         

Примеры

На следующей диаграмме вы можете видеть, как слово caféбыло закодировано в кодировке «UTF-8» или «Cp1252» в зависимости от типа терминала. В обоих примерах cafэто просто обычные ascii. В UTF-8 éкодируется с использованием двух байтов. В «Cp1252» é равно 0xE9 (что также является значением точки Unicode (это не совпадение)). Вызывается правильный decode()код, и преобразование в Юникод Python прошло успешно: Диаграмма строки, конвертируемой в строку Python Unicode

На этой диаграмме decode()вызывается с ascii(что аналогично вызову unicode()без заданной кодировки). Поскольку ASCII не может содержать байтов больше чем 0x7F, это вызовет UnicodeDecodeErrorисключение:

Диаграмма строки, конвертируемой в строку Python Unicode с неправильной кодировкой

Юникод сэндвич

Хорошей практикой является формирование сэндвича Unicode в вашем коде, где вы декодируете все входящие данные в строки Unicode, работаете с Unicodes, а затем кодируете в strs при выходе. Это избавит вас от беспокойства о кодировании строк в середине вашего кода.

Ввод / Декодирование

Исходный код

Если вам нужно добавить не-ASCII в ваш исходный код, просто создайте строки в Юникоде, добавив к префиксу строку u. Например

u'Zürich'

Чтобы позволить Python декодировать ваш исходный код, вам необходимо добавить заголовок кодирования, соответствующий фактической кодировке вашего файла. Например, если ваш файл был закодирован как «UTF-8», вы должны использовать:

# encoding: utf-8

Это необходимо только в том случае, если в вашем исходном коде не-ASCII .

файлы

Обычно не-ASCII данные получаются из файла. ioМодуль обеспечивает TextWrapper , который декодирует файл на лету, используя заданный encoding. Вы должны использовать правильную кодировку для файла - это не может быть легко угадано. Например, для файла UTF-8:

import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
     my_unicode_string = my_file.read() 

my_unicode_stringтогда будет подходящим для перехода к Markdown. Если UnicodeDecodeErrorиз read()строки, то вы, вероятно, использовали неправильное значение кодировки.

CSV файлы

Модуль Python 2.7 CSV не поддерживает символы не ASCII 😩. Однако помощь доступна с https://pypi.python.org/pypi/backports.csv .

Используйте его как выше, но передайте ему открытый файл:

from backports import csv
import io
with io.open("my_utf8_file.txt", "r", encoding="utf-8") as my_file:
    for row in csv.reader(my_file):
        yield row

Базы данных

Большинство драйверов баз данных Python могут возвращать данные в Unicode, но обычно требуют небольшой настройки. Всегда используйте строки Unicode для запросов SQL.

MySQL

В строке подключения добавьте:

charset='utf8',
use_unicode=True

Например

>>> db = MySQLdb.connect(host="localhost", user='root', passwd='passwd', db='sandbox', use_unicode=True, charset="utf8")
PostgreSQL

Добавить:

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

HTTP

Веб-страницы могут быть закодированы практически в любой кодировке. Content-typeЗаголовок должен содержать charsetполе намек на кодировании. Затем содержимое может быть декодировано вручную в соответствии с этим значением. Кроме того, Python-Requests возвращает Unicodes в response.text.

Вручную

Если вам нужно декодировать строки вручную, вы можете просто сделать my_string.decode(encoding), где encodingнаходится соответствующая кодировка. Python 2.x поддерживаемые кодеки приведены здесь: Стандартные кодировки . Опять же, если вы получите, UnicodeDecodeErrorто, вероятно, вы ошиблись кодировкой.

Мясо бутерброда

Работайте с Unicodes так же, как с обычными strs.

Вывод

стандартный вывод / печать

printпишет через поток stdout. Python пытается настроить кодировщик на стандартный вывод, чтобы Unicodes кодировались в кодировку консоли. Например, если оболочка Linux localeесть en_GB.UTF-8, выходные данные будут закодированы в UTF-8. В Windows вы будете ограничены 8-битной кодовой страницей.

Неправильно настроенная консоль, например поврежденная локаль, может привести к неожиданным ошибкам печати. PYTHONIOENCODINGПеременная окружения может форсировать кодирование для stdout.

файлы

Так же, как ввод, io.openможет использоваться для прозрачного преобразования Unicodes в закодированные байтовые строки.

База данных

Та же конфигурация для чтения позволит писать Unicodes напрямую.

Python 3

Python 3 не более Unicode способен, чем Python 2.x, однако он немного меньше запутан в теме. Например, регулярная strстрока теперь является строкой Юникода, а старая str- теперь bytes.

Кодировка по умолчанию - UTF-8, поэтому, если вы .decode()используете байтовую строку без кодировки, Python 3 использует кодировку UTF-8. Это, вероятно, решает 50% проблем Unicode людей.

Кроме того, open()по умолчанию работает в текстовом режиме, поэтому возвращает декодированный str(Unicode). Кодировка получена из вашей локали, которая имеет тенденцию быть UTF-8 в системах Un * x или 8-битной кодовой страницей, такой как windows-1251, в блоках Windows.

Почему вы не должны использовать sys.setdefaultencoding('utf8')

Это неприятный хак (есть причина, которую вы должны использовать reload), который только маскирует проблемы и мешает переходу на Python 3.x. Разберитесь в проблеме, устраните причину и наслаждайтесь Unicode ZEN. См. Почему мы НЕ должны использовать sys.setdefaultencoding ("utf-8") в скрипте py? для дальнейших деталей


2
Для тех, кто ищет ответы на Python 2, более полезный TLDR: использовать io.openдля чтения / записи файлов, использовать from __future__ import unicode_literals, настраивать другие вводы / выводы данных (например, базы данных) для использования Unicode.
idbrii

ооочень как мы это исправим? LOL, это не проблема написания сценария - это установка его
Мэтью

@ Матвей попробуйте настройку PYTHONIOENCODING=utf-8. Если это не помогает, вам нужно связаться с автором сценария, чтобы исправить его код.
Аластер МакКормак

498

Наконец то я понял:

as3:/usr/local/lib/python2.7/site-packages# cat sitecustomize.py
# encoding=utf8  
import sys  

reload(sys)  
sys.setdefaultencoding('utf8')

Дай мне проверить:

as3:~/ngokevin-site# python
Python 2.7.6 (default, Dec  6 2013, 14:49:02)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> reload(sys)
<module 'sys' (built-in)>
>>> sys.getdefaultencoding()
'utf8'
>>>

Выше показана кодировка по умолчанию для python utf8. Тогда ошибки больше нет.


7
Я пытаюсь это сделать, но это не может изменить кодировку навсегда. После выхода из консоли Python и запуска снова кодировка остается прежней
macemers

37
Спасибо! Но почему мы должны перезагрузить sys после его импорта?
Дмитри

6
@DmitryNarkevich, из-за функции Illusive setdefaultencoding . Он удаляется при запуске Python, так как он, очевидно, никогда не должен был быть частью правильного релиза.
Пред

3
Это означает, что вы не устранили основную причину. Вы только что исправили любое подразумеваемое преобразование
Аластер МакКормак

5
@miraculixx Стандартная кодировка Python 3 - UTF-8 со строками Unicode в качестве значения по умолчанию str, так что это не просрочено. В Python 2.x Unicode находился в переходном состоянии, поэтому было бы опасно предполагать кодировку при преобразовании байтов в Unicodes. Таким образом, кодировка ASCII по умолчанию в Py2 была осознанным выбором, и поэтому изменение кодировки по умолчанию требует преднамеренного взлома перезагрузки sys. Правильный способ устранения ошибок кодирования в Py2 - это однозначно декодировать и кодировать (байтовые) строки в Unicode, когда преобразования необходимы, а не просто предполагать, что строки кодируются в UTF-8.
Аластер МакКормак,

130

Это классический «вопрос Юникода». Я считаю, что объяснение этого выходит за рамки ответа StackOverflow, чтобы полностью объяснить, что происходит.

Это хорошо объяснено здесь .

В очень кратком изложении вы передали что-то, что интерпретируется как строка байтов, чему-то, что должно декодировать его в символы Unicode, но кодек по умолчанию (ascii) не работает.

В презентации, на которую я вам указал, дается совет, как этого избежать. Сделайте ваш код "бутербродом с Юникодом". В Python 2 использование from __future__ import unicode_literalsподсказок.

Обновление: как исправить код:

ОК - в вашей переменной «source» у вас есть несколько байтов. Из вашего вопроса не понятно, как они туда попали - может быть, вы читаете их из веб-формы? В любом случае они не кодируются с помощью ascii, но python пытается преобразовать их в Unicode, предполагая, что они есть. Вы должны явно сказать ему, что такое кодировка. Это означает, что вам нужно знать, что такое кодировка! Это не всегда легко, и это полностью зависит от того, откуда взялась эта строка. Вы можете поэкспериментировать с некоторыми распространенными кодировками - например, UTF-8. Вы указываете unicode () кодировку как второй параметр:

source = unicode(source, 'utf-8')

1
Это все еще головная боль. GreenAsJade, вы можете дать мне конкретное решение?
рыбак

1
Вы спрашиваете: «Как я, как пользователь этого блога, могу избежать этой проблемы?». Или у вас вопрос "как я могу исправить код, чтобы эта проблема не возникала"?
GreenAsJade

2
Г-н Гринасхейд: куда мне поместить "source = unicode (source, 'utf-8')"?
рыбак

7
Странно ... после положительного отзыва в течение года, вдруг два отрицательных голоса ... А?
GreenAsJade

11
используйте currentFile = open(filename, 'rt', encoding='latin1')или currentFile = open(filename, 'rt', encoding='utf-8')- см. здесь: stackoverflow.com/a/23917799/2047442
irudyak

42

В некоторых случаях, когда вы проверяете кодировку по умолчанию ( print sys.getdefaultencoding()), возвращается, что вы используете ASCII. Если вы переключитесь на UTF-8, он не будет работать, в зависимости от содержимого вашей переменной. Я нашел другой способ:

import sys
reload(sys)  
sys.setdefaultencoding('Cp1252')

Ой, это сработало для моей проблемы с Python, бросавшим UnicodeDecodeError на var = u "" "var large string" ""
user2426679

AttributeError: модуль 'sys' не имеет атрибута 'setdefaultencoding'
Chaine

и reload(sys)используется по этой конкретной причине.
Марчин Орловски

1
Работал на меня! СПАСИБО !
Мацей

22

Я искал, чтобы решить следующее сообщение об ошибке:

unicodedecodeerror: кодек «ascii» не может декодировать байт 0xe2 в позиции 5454: порядковый номер не в диапазоне (128)

Я наконец исправил это, указав кодировку:

f = open('../glove/glove.6B.100d.txt', encoding="utf-8")

Хотелось бы, чтобы это тебе тоже помогло.


это решило ошибку для меня при чтении / записи файлов .csv, не нуждалось ни в каких других вещах, перечисленных в других ответах
user5359531

Я не понимаю, почему другие ответы предоставляют так много деталей ... но забыть об этом простом решении. +10!
stan0

18
"UnicodeDecodeError: 'ascii' codec can't decode byte"

Причина этой ошибки: input_string должен быть Unicode, но был указан str

"TypeError: Decoding Unicode is not supported"

Причина этой ошибки: попытка конвертировать unicode input_string в unicode


Итак, сначала проверьте, что ваша input_string является strи преобразовать в Unicode, если необходимо:

if isinstance(input_string, str):
   input_string = unicode(input_string, 'utf-8')

Во-вторых, вышеприведенное просто меняет тип, но не удаляет символы не ascii. Если вы хотите удалить не-ascii символы:

if isinstance(input_string, str):
   input_string = input_string.decode('ascii', 'ignore').encode('ascii') #note: this removes the character and encodes back to string.

elif isinstance(input_string, unicode):
   input_string = input_string.encode('ascii', 'ignore')

9

Я считаю, что лучше всего всегда преобразовывать в Unicode, но этого трудно достичь, потому что на практике вам придется проверять и преобразовывать каждый аргумент для каждой функции и метода, которые вы когда-либо пишете, включая некоторую форму обработки строк.

Таким образом, я придумал следующий подход, чтобы гарантировать либо юникод, либо байтовые строки из любого ввода. Вкратце, включите и используйте следующие лямбды:

# guarantee unicode string
_u = lambda t: t.decode('UTF-8', 'replace') if isinstance(t, str) else t
_uu = lambda *tt: tuple(_u(t) for t in tt) 
# guarantee byte string in UTF8 encoding
_u8 = lambda t: t.encode('UTF-8', 'replace') if isinstance(t, unicode) else t
_uu8 = lambda *tt: tuple(_u8(t) for t in tt)

Примеры:

text='Some string with codes > 127, like Zürich'
utext=u'Some string with codes > 127, like Zürich'
print "==> with _u, _uu"
print _u(text), type(_u(text))
print _u(utext), type(_u(utext))
print _uu(text, utext), type(_uu(text, utext))
print "==> with u8, uu8"
print _u8(text), type(_u8(text))
print _u8(utext), type(_u8(utext))
print _uu8(text, utext), type(_uu8(text, utext))
# with % formatting, always use _u() and _uu()
print "Some unknown input %s" % _u(text)
print "Multiple inputs %s, %s" % _uu(text, text)
# but with string.format be sure to always work with unicode strings
print u"Also works with formats: {}".format(_u(text))
print u"Also works with formats: {},{}".format(*_uu(text, text))
# ... or use _u8 and _uu8, because string.format expects byte strings
print "Also works with formats: {}".format(_u8(text))
print "Also works with formats: {},{}".format(*_uu8(text, text))

Вот еще несколько рассуждений по этому поводу .


Привет, в Python 3 функция _u не работает с этим значением 'Ita £'.
Мартин

1
Хорошо, с чего начать ваши "рассуждения"? print unicode(u'Zürich', encoding="UTF-8")а затем жалуются: «Но удивительно, что вы не можете кодировать Unicode Ext в UTF8». unicode()не кодирует; он декодирует, и вы не можете декодировать Unicode - он уже декодирован!
Аластер МакКормак

@AlastairMcCormack Вы можете улучшить пост. Однако, если вы предпочитаете распространять свой предполагаемый превосходство над всеми остальными, кто не разделяет ваше мнение и понимание, я, честно говоря, не заинтересован. Спасибо.
miraculixx

3
@miraculixx Извините, я не хотел показаться вам придурком. Беспокоиться о декодировании и кодировании каждый раз, когда вы используете строку в своем коде, просто не нужно.
Аластер МакКормак

7

Чтобы решить эту проблему на уровне операционной системы в установке Ubuntu, проверьте следующее:

$ locale charmap

Если вы получаете

locale: Cannot set LC_CTYPE to default locale: No such file or directory

вместо

UTF-8

затем установить LC_CTYPE и LC_ALLвот так:

$ export LC_ALL="en_US.UTF-8"
$ export LC_CTYPE="en_US.UTF-8"

6

Encode преобразует объект Unicode в строковый объект. Я думаю, что вы пытаетесь закодировать строковый объект. сначала преобразуйте ваш результат в объект Unicode, а затем закодируйте этот объект Unicode в UTF-8. например

    result = yourFunction()
    result.decode().encode('utf-8')

4

У меня была та же проблема, но она не работала для Python 3. Я последовал этому, и это решило мою проблему:

enc = sys.getdefaultencoding()
file = open(menu, "r", encoding = enc)

Вы должны установить кодировку при чтении / записи файла.


4

Получил ту же ошибку, и это решило мою ошибку. Спасибо! Python 2 и Python 3, отличающиеся обработкой Unicode, делают маринованные файлы совершенно несовместимыми для загрузки. Так что используйте аргумент кодирования Python pickle. Ссылка ниже помогла мне решить аналогичную проблему, когда я пытался открыть маринованные данные из моего Python 3.7, в то время как мой файл был изначально сохранен в версии Python 2.x. https://blog.modest-destiny.com/posts/python-2-and-3-compatible-pickle-save-and-load/ Я копирую функцию load_pickle в своем скрипте и вызываю load_pickle (pickle_file) во время загрузки моего input_data, как это:

input_data = load_pickle("my_dataset.pkl")

Функция load_pickle находится здесь:

def load_pickle(pickle_file):
    try:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f)
    except UnicodeDecodeError as e:
        with open(pickle_file, 'rb') as f:
            pickle_data = pickle.load(f, encoding='latin1')
    except Exception as e:
        print('Unable to load data ', pickle_file, ':', e)
        raise
    return pickle_data

1
определение load_pickleфункции лучше включить в ваш ответ.
Саняш


3

Короче говоря, чтобы обеспечить правильную обработку Юникода в Python 2:

  • использовать io.openдля чтения / записи файлов
  • использование from __future__ import unicode_literals
  • настроить другие входы / выходы данных (например, базы данных, сеть) для использования Unicode
  • если вы не можете сконфигурировать выходные данные в utf-8, конвертируйте свои выходные данные для них print(text.encode('ascii', 'replace').decode())

Для объяснения см. Подробный ответ @Alastair McCormack .


• использовать io.open(path, 'r', encoding='utf-8')для чтения файлов в кодировке utf-8.
Боб Стейн

3

У меня была та же ошибка, с URL-адресами, содержащими символы не ascii (байты со значениями> 128), мое решение:

url = url.decode('utf8').encode('utf-8')

Примечание: utf-8, utf8 - это просто псевдонимы. Использование только utf8 или utf-8 должно работать точно так же

В моем случае, работавшем для меня, в Python 2.7, я предполагаю, что это назначение изменило «что-то» во strвнутреннем представлении - то есть оно вызывает правильное декодирование последовательности байтов с резервной копией urlи, наконец, помещает строку в utf-8 str с вся магия в нужном месте. Unicode в Python для меня черная магия. Надеюсь, полезно


1
Почему черта в одном, а не в другом
Игорь Ганапольский

1
Python принимает псевдонимы для кодирования имен, я попробовал сейчас, и выполнил то же самое ... просто я не заметил, что я написал их по-другому, добавил примечание
Фабиано Тарлао

2

У меня возникла та же проблема со строкой «PastelerÃa Mallorca», и я решил:

unicode("Pastelería Mallorca", 'latin-1')

1

В проекте Django (1.9.10) / Python 2.7.5 у меня есть частые UnicodeDecodeErrorисключения; главным образом, когда я пытаюсь передать строки юникода в логирование. Я сделал вспомогательную функцию для произвольных объектов, чтобы в основном форматировать в 8-битные строки ascii и заменять любые символы, отсутствующие в таблице, на «?». Я думаю, что это не лучшее решение, но так как кодировкой по умолчанию является ascii (и я не хочу ее менять), она подойдет:

def encode_for_logging (c, encoding = 'ascii'):
    если isinstance (c, базовая строка):
        вернуть c.encode (кодировка, «заменить»)
    elif isinstance (c, Iterable):
        c_ = []
        для V в C:
            c_.append (encode_for_logging (v, кодировка))
        возврат c_
    еще:
        вернуть encode_for_logging (unicode (c))
`


1

Эта ошибка возникает, когда в нашей строке есть символы, не входящие в ASCII, и мы выполняем любые операции с этой строкой без надлежащего декодирования. Это помогло мне решить мою проблему. Я читаю файл CSV с идентификатором столбцов, текстом и расшифровкой символов, как показано ниже:

train_df = pd.read_csv("Example.csv")
train_data = train_df.values
for i in train_data:
    print("ID :" + i[0])
    text = i[1].decode("utf-8",errors="ignore").strip().lower()
    print("Text: " + text)

0

Вот мое решение, просто добавьте кодировку. with open(file, encoding='utf8') as f

А поскольку чтение файла перчаток займет много времени, я рекомендую перчатку перетянуть в файл с непостоянством. Когда в течение netx вы прочитаете веса встраивания, это сэкономит ваше время.

import numpy as np
from tqdm import tqdm


def load_glove(file):
    """Loads GloVe vectors in numpy array.
    Args:
        file (str): a path to a glove file.
    Return:
        dict: a dict of numpy arrays.
    """
    embeddings_index = {}
    with open(file, encoding='utf8') as f:
        for i, line in tqdm(enumerate(f)):
            values = line.split()
            word = ''.join(values[:-300])
            coefs = np.asarray(values[-300:], dtype='float32')
            embeddings_index[word] = coefs

    return embeddings_index

# EMBEDDING_PATH = '../embedding_weights/glove.840B.300d.txt'
EMBEDDING_PATH = 'glove.840B.300d.txt'
embeddings = load_glove(EMBEDDING_PATH)

np.save('glove_embeddings.npy', embeddings) 

Ссылка Gist: https://gist.github.com/BrambleXu/634a844cdd3cd04bb2e3ba3c83aef227


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.