Ruby & Ruby on Rails « Как правильно избавиться от ошибки Invalid byte sequence in utf−8?

Описание проблемы:

Беру к примеру 2 линка
1. http://www.ariatender.com/beta/
2. http://www.ariatender.com/beta/tender-by-category.php
По средством джема Mechanize дергаю каждый из них в порядке очереди. Контент каждой из полученных страниц я обрабатываю регулярками, отсекаю хтмл тэги, весь мусор, и оставляю чистый текст.
Проблема состоит в том, что по линку №1 всё ок. А на линке №2 у меня вылазит ошибка Invalid byte sequence in utf-8 как только я пытаюсь прикоснутся к контенту страницы gub'ом или split'ом

Меры которые я предпринимал и что из этого получилось:

/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .ruby.geshi_code {font-family:monospace;} .ruby.geshi_code .imp {font-weight: bold; color: red;} .ruby.geshi_code .kw1 {color:#9966CC; font-weight:bold;} .ruby.geshi_code .kw2 {color:#0000FF; font-weight:bold;} .ruby.geshi_code .kw3 {color:#CC0066; font-weight:bold;} .ruby.geshi_code .kw4 {color:#CC00FF; font-weight:bold;} .ruby.geshi_code .co1 {color:#008000; font-style:italic;} .ruby.geshi_code .coMULTI {color:#000080; font-style:italic;} .ruby.geshi_code .es0 {color:#000099;} .ruby.geshi_code .br0 {color:#006600; font-weight:bold;} .ruby.geshi_code .sy0 {color:#006600; font-weight:bold;} .ruby.geshi_code .st0 {color:#996600;} .ruby.geshi_code .nu0 {color:#006666;} .ruby.geshi_code .me1 {color:#9900CC;} .ruby.geshi_code .re0 {color:#ff6633; font-weight:bold;} .ruby.geshi_code .re1 {color:#0066ff; font-weight:bold;} .ruby.geshi_code .re2 {color:#6666ff; font-weight:bold;} .ruby.geshi_code .re3 {color:#ff3333; font-weight:bold;} .ruby.geshi_code span.xtra { display:block; }
force_ecoding('utf-8') # ошибка остается
encode('UTF-8', 'UTF-8', invalid: :replace, undef: :replace, replace: '') # ошибка остается
encode('UTF-8', invalid: :replace, undef: :replace, replace: '') # творится что-то мне непонятное. Почему-то вся арабская абракадабра чудесным образом исчезает, хотя я ожидал что исчезнут только проблемные байты и дадут мне спокойно работать.

Если ты не против помочь разобраться в вопросе, писанина снизу для тебя.
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .ruby.geshi_code {font-family:monospace;} .ruby.geshi_code .imp {font-weight: bold; color: red;} .ruby.geshi_code .kw1 {color:#9966CC; font-weight:bold;} .ruby.geshi_code .kw2 {color:#0000FF; font-weight:bold;} .ruby.geshi_code .kw3 {color:#CC0066; font-weight:bold;} .ruby.geshi_code .kw4 {color:#CC00FF; font-weight:bold;} .ruby.geshi_code .co1 {color:#008000; font-style:italic;} .ruby.geshi_code .coMULTI {color:#000080; font-style:italic;} .ruby.geshi_code .es0 {color:#000099;} .ruby.geshi_code .br0 {color:#006600; font-weight:bold;} .ruby.geshi_code .sy0 {color:#006600; font-weight:bold;} .ruby.geshi_code .st0 {color:#996600;} .ruby.geshi_code .nu0 {color:#006666;} .ruby.geshi_code .me1 {color:#9900CC;} .ruby.geshi_code .re0 {color:#ff6633; font-weight:bold;} .ruby.geshi_code .re1 {color:#0066ff; font-weight:bold;} .ruby.geshi_code .re2 {color:#6666ff; font-weight:bold;} .ruby.geshi_code .re3 {color:#ff3333; font-weight:bold;} .ruby.geshi_code span.xtra { display:block; }
require 'mechanize'
require 'logger'

pages = ['http://www.ariatender.com/beta/', 'http://www.ariatender.com/beta/tender-by-category.php']
agent = Mechanize.new
agent.user_agent_alias ='Mac Safari'
agent.log = Logger.new(File.join(File.dirname(__FILE__), 'log.txt'))


pages.each do |page|
  begin
    agent.log.debug("Page: #{page}")
    content = agent.get(page)
    enc = content.body.force_encoding('utf-8')
    agent.log.debug("Content: #{enc}")
    striped_tags = enc.gsub(/<[^>]+?>/m, ' ')
    agent.log.debug("Modify content: #{striped_tags}")
  rescue
    agent.log.error($!.message)
    agent.log.error($!.backtrace.join("n"))
  end
end

1 ответов


Решил вопрос через глубокий анус, как у меня к сожалению часто бывает.
Т.к. у меня упорно не получалось пользоваться :invalid=>:replace, :undef=>:replace (менялись все символы не попадающие в ascii) пришлось сделать это самому. Я пробежался по каждому символу строки, и отсек невалидные символы.

source.each_char do |char|
  enc_char = char.force_encoding('utf-8')
  if enc_char.valid_encoding?
    content << enc_char
  else
    log.debug(char)
  end
end

Если у когото есть более изящное решение, буду признателен если поделитесь.