Вот уже пару месяцев я работаю над своим дипломным проектом. В чем там суть пока раскрывать не буду, но проект на Ruby on Rails – давно уже хотелось посмотреть, что это и с чем его едят. Впечатления сплошь положительные, и лишь один момент с кодировками заставил меня поматериться – об этом и пойдет речь.
Суть проблемы
Я получаю данные с разных сайтов через
1 |
response = Net::HTTP.get_response(URI.parse(URI.encode(url))) |
response = Net::HTTP.get_response(URI.parse(URI.encode(url)))
Дальше обрабатываю response.body, и все в теории красиво. Но при наличии среди полученных данных кириллицы я в базе получала совсем не то, что хотелось, а что-то типа »\xCB» вместо кириллического символа. На базу грешить не приходится, при сохранении кириллицы обычным post’ом проблем нет. Значит дело в самих данных.
Попытки решения
response.body имеет кодировку ASCII-8BIT. Дефолтная кодировка проекта UTF-8.
1 |
response.body.encode! |
response.body.encode!
ничего не изменил
1 2 |
response.body.encode('utf-8', 'binary', :invalid => :replace, :undef => :replace, :replace => '') |
response.body.encode('utf-8', 'binary', :invalid => :replace,
:undef => :replace, :replace => '')
– просто выпиливает кириллицу
1 |
response.body.force_encoding("UTF-8) |
response.body.force_encoding("UTF-8)
– возвращает ерунуду со знаками вопроса вместо кириллицы
Поочередное преобразование
1 2 |
response.body.force_encoding("windows-1251) response.body.encode! |
response.body.force_encoding("windows-1251)
response.body.encode!
для некоторых сайтов сработало, но все же часто возвращало ������. Как так? Везде charset=UTF-8. Но раз преобразование к windows-1251 помогло, надо танцевать отсюда.
И вот оно, чудо!
Окончательным решением вопроса стала вот такая обработка:
1 2 3 4 5 6 7 8 9 |
begin cleaned = response.body.dup.force_encoding('UTF-8') unless cleaned.valid_encoding? cleaned = response.body.encode( 'UTF-8', 'Windows-1251' ) end content = cleaned rescue EncodingError content.encode!( 'UTF-8', invalid: :replace, undef: :replace ) end |
begin
cleaned = response.body.dup.force_encoding('UTF-8')
unless cleaned.valid_encoding?
cleaned = response.body.encode( 'UTF-8', 'Windows-1251' )
end
content = cleaned
rescue EncodingError
content.encode!( 'UTF-8', invalid: :replace, undef: :replace )
end
Спасибо гуглу)
Не забываем поделиться!
