#source file is encoded in utf8
import urllib2
import re
req = urllib2.urlopen('http://people.w3.org/rishida/scripts/samples/hungarian.html')
c = req.read()#.decode('utf-8')
p = r'title="This is Latin script \(Hungarian language\)">(.+)'
text = re.search(p, c).group(1)
name = text[:10]+'.txt' #file name will have special chars in it
f = open(name, 'wb')
f.write(text) #content of file will have special chars in it
f.close()
x = raw_input('done')
Как вы видите, script выполняет пару вещей: - Читает содержимое, которое, как известно, имеет символы Юникода с веб-страницы в переменную
(Исходный файл сохраняется в utf- 8, но это не должно иметь значения, если строки кода unicode в действительности не определены в исходном коде... Как вы можете видеть, строка unicode динамически определяется в переменной. что кодировка источника не имеет значения в этом сценарии)
Здесь странное поведение, которое я получаю (Windows 7, Python 2.7): Когда я не использую функцию декодирования:
c = req.read()
ИМЯ файла выйдет из тарабарщины, но СОДЕРЖАНИЕ файла выйдет читабельным (то есть вы увидите верные венгерские символы юникода)
Тем не менее, когда я использую функцию декодирования:
c = req.read().decode('utf-8')
Он не будет ОШИБКА при открытии файла (действительно создавая его с режимом "w" ) и полученный файл NAME будет доступен для чтения, да, теперь он показывает правильные символы юникода.
До сих пор так хорошо? Ну, тогда WILL ERROR попытается записать содержимое юникода в файл:
f.write(text) #content of file will have special chars in it
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe1' in position 8: ordinal not in range(128)
Видишь ли, я не могу иметь торт и съесть его тоже... Либо я могу правильно записать ИМЯ файла, либо я могу правильно записать СОДЕРЖАНИЕ файла.
Как я могу сделать оба?
Я также попытался записать файл с помощью
f = codecs.open(name, encoding='utf-8', mode='wb')
Но это также ошибки..
В то время как ответ winterTTR работает. Я понял, что этот подход запутан. Скорее всего, все, что вам действительно нужно сделать, это кодировать данные, которые вы пишете в файл. Имя, которое вам не нужно кодировать, и имя, и содержание будут выдаваться "читаемыми".
content = '\xunicode chars'.decode('utf-8')
f = open(content[:5]+'.txt', 'wb')
f.write(content.encode('utf-8'))
f.close()
Единственная проблема для вас - это просто "нечитаемое" имя файла из исходного исходного файла. Это может решить вашу проблему:
f = open(name.decode('utf-8').encode( sys.getfilesystemencoding() ) , 'wb')