Когда вы печатаете его в командной строке, вы выводите строку Unicode на терминал. Терминал имеет кодировку, поэтому Python закодирует вашу строку Unicode в эту кодировку. Это будет хорошо работать.
Когда вы используете его в CGI, вы в конечном итоге печатаете на стандартный вывод, у которого нет кодировки. Поэтому Python пытается закодировать строку с помощью ASCII. Это терпит неудачу, так как ASCII не содержит все символы, которые вы пытаетесь напечатать, поэтому вы получаете вышеуказанную ошибку.
Исправление для этого состоит в том, чтобы закодировать вашу строку в какую-то кодировку (почему бы не UTF8?), А также сказать это в заголовке.
Так что-то вроде этого:
sys.stdout.buffer.write(b"Content-type: text/html;encoding=UTF-8\n\n") # Not 100% sure about the spelling.
sys.stdout.buffer.write(site.encode('UTF8'))
В Python 2 это также будет работать:
print("Content-type: text/html;encoding=UTF-8\n\n") # Not 100% sure about the spelling.
print(site.encode('UTF8'))
Но в Python 3 закодированные данные в байтах, поэтому они не будут хорошо печататься.
Конечно, вы заметите, что теперь вы сначала декодируете из UTF8, а затем перекодируете его. Строго говоря, вам не нужно этого делать. Но если вы хотите изменить промежуточный HTML-код, это может быть хорошей идеей и сохранить все изменения в Unicode.