我在Ruby(1.9)中編寫了一個爬取程序,它從很多隨機站點中消耗大量HTML。
當試圖提取鏈接時,我決定只使用.scan(/href="(.*?)"/i)
而不是nokogiri/hpricot(主要加速)。問題是我現在收到很多「invalid byte sequence in UTF-8
」錯誤。
從我的理解,net/http
庫沒有任何編碼的具體選項,並進來的東西基本上沒有正確標記。
實際使用傳入數據的最佳方式是什麼?我試圖.encode
與取代的和無效的選項集,但是沒有成功,到目前爲止...ruby 1.9:UTF-8中的字節順序無效
回答
您使用scan
之前,請確保所請求的頁面的Content-Type
頭是text/html
,因爲可以有鏈接之類的東西哪些是圖像沒有用UTF-8編碼。如果您在<link>
元素中挑選了href
,該頁面也可能不是html。如何檢查這一點取決於您使用的HTTP庫。然後,確保結果僅爲String#ascii_only?
(不是UTF-8,因爲HTML只能使用ascii,否則可以使用實體)。如果這兩項測試都通過,則使用scan
是安全的。
我建議你使用HTML解析器。找到最快的一個。
解析HTML並不像看起來那麼容易。
瀏覽器在UTF-8 HTML文檔中解析無效的UTF-8序列,只是放上「 」符號。所以一旦HTML中的無效UTF-8序列被解析,結果文本就是一個有效的字符串。
即使裏面的屬性值,你必須解碼HTML實體,如放
下面是總結了,爲什麼你不能可靠地解析HTML使用正則表達式一個很大的問題: RegEx match open tags except XHTML self-contained tags
我很想保留正則表達式,因爲它快了10倍,我真的不想正確解析html,只是想提取鏈接。 我應該可以通過以下操作替換ruby中的無效部分: ok_string = bad_string.encode(「UTF-8」,{:invalid =>:replace,:undef =>:替換}) 但是,似乎沒有工作:( – 2010-06-06 11:02:43
我遇到字符串,其中有英文,俄文和其他一些字母的混合,這引起了異常。我只需要俄語和英語,而目前這對我的作品:
ec1 = Encoding::Converter.new "UTF-8","Windows-1251",:invalid=>:replace,:undef=>:replace,:replace=>""
ec2 = Encoding::Converter.new "Windows-1251","UTF-8",:invalid=>:replace,:undef=>:replace,:replace=>""
t = ec2.convert ec1.convert t
我目前的解決方案是運行:
my_string.unpack("C*").pack("U*")
這將至少幹掉這是我的主要問題
例外的我正在使用這種方法結合'valid_encoding?',它似乎檢測什麼時候發生了什麼錯誤。'val.unpack('C *')。pack('U *')if! val.valid_encoding?'。 – 2012-01-19 16:41:43
這一個爲我工作,成功地將我的'\ xB0'轉換回度符號,甚至'valid_encoding?'回來,但我仍然檢查它是否不正確,並刪除使用的字符上面的答案是:'string.encode!('UTF-8','binary',invalid::replace,undef::replace,replace:'')'我也嘗試過'force_encoding'路由,但是失敗了。 – hamstar 2014-08-04 23:48:19
這很好,謝謝。 – 2015-12-17 03:58:53
在Ruby 1.9.3中,可以使用String.encode來「忽略」無效的UTF-8序列。下面是一個片段,將在1.8(iconv)和1.9工作都(String#encode):
require 'iconv' unless String.method_defined?(:encode)
if String.method_defined?(:encode)
file_contents.encode!('UTF-8', 'UTF-8', :invalid => :replace)
else
ic = Iconv.new('UTF-8', 'UTF-8//IGNORE')
file_contents = ic.iconv(file_contents)
end
,或者如果你真的有麻煩的輸入,你可以做從UTF-8雙轉換爲UTF-16和回UTF-8:
require 'iconv' unless String.method_defined?(:encode)
if String.method_defined?(:encode)
file_contents.encode!('UTF-16', 'UTF-8', :invalid => :replace, :replace => '')
file_contents.encode!('UTF-8', 'UTF-16')
else
ic = Iconv.new('UTF-8', 'UTF-8//IGNORE')
file_contents = ic.iconv(file_contents)
end
我比較過根據我的解決方案,我發現,我的遺失了一些信件,至少是'ё':'「Alena V。\」'。儘管你的解決方案保留了它:'「Ale \ u0308na V。\」'。尼斯。 – Nakilon 2012-01-16 01:20:07
對於一些有問題的輸入,我還使用了從UTF-8到UTF-16的雙重轉換,然後返回到UTF-8'file_contents.encode!('UTF-16','UTF-8',:invalid =>:replace ,:replace =>'')'file_contents.encode!('UTF-8','UTF-16')' – ecerulm 2012-01-16 09:28:49
還有'force_encoding'的選項。如果讀取ISO8859-1作爲UTF-8(因此該字符串包含無效的UTF-8),那麼可以使用the_string.force_encoding(「ISO8859-1」)將其重新解釋爲ISO8859-1,並且工作正常與它的真正的編碼字符串。 – ecerulm 2012-02-20 14:36:06
雖然Nakilon的解決方案有效,至少儘可能讓過去的錯誤,在我的情況,我有這個奇怪的F-編了字符從Microsoft Excel始發轉換爲CSV這是登記在紅寶石作爲(得到這個)紅寶石K是一個粗體K.爲了解決這個問題,我用'iso-8859-1'即。CSV.parse(f, :encoding => "iso-8859-1")
,它把我的任性deaky西里爾K公司的進入更易於管理/\xCA/
,我會再與string.gsub!(/\xCA/, '')
同樣,我只想指出,雖然Nakilon(和其他人)修復程序是爲源自(哈哈)Cyrillia的西里爾字符,但此輸出是從xls轉換而來的csv的標準輸出! – 2012-10-16 03:57:18
這似乎是工作刪除:
def sanitize_utf8(string)
return nil if string.nil?
return string if string.valid_encoding?
string.chars.select { |c| c.valid_encoding? }.join
end
接受的答案,也不是我的其他答案的工作。我發現this post其中建議
string.encode!('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
這解決了我的問題。
這解決了我的問題,我喜歡使用非棄用的方法(我現在有Ruby 2.0)。 – 2014-04-26 19:51:42
這是唯一的作品!我已經嘗試了所有上述方案的,他們沒有工作 字符串,在測試 使用 「fdsfdsf dfsf的SFD FS自衛隊
fooo??? {[email protected]#$%^&*()_+}
如果你不這樣做你可以做類似的數據「照顧」:
search_params = params[:search].valid_encoding? ? params[:search].gsub(/\W+/, '') : "nothing"
我只是用valid_encoding?
以獲得通過的。我是一個搜索領域,所以我一遍又一遍地發現同樣的怪異,所以我使用了類似的東西:只是爲了讓系統不中斷。由於我不會控制用戶體驗以在發送此信息之前進行自動驗證(例如自動反饋說「虛擬起來!」),所以我可以將它取出,將其除去並返回空白結果。
試試這個:
def to_utf8(str)
str = str.force_encoding('UTF-8')
return str if str.valid_encoding?
str.encode("UTF-8", 'binary', invalid: :replace, undef: :replace, replace: '')
end
最佳答案我案件!謝謝 – Aldo 2016-01-19 10:17:40
attachment = file.read
begin
# Try it as UTF-8 directly
cleaned = attachment.dup.force_encoding('UTF-8')
unless cleaned.valid_encoding?
# Some of it might be old Windows code page
cleaned = attachment.encode('UTF-8', 'Windows-1252')
end
attachment = cleaned
rescue EncodingError
# Force it to UTF-8, throwing out invalid bits
attachment = attachment.force_encoding("ISO-8859-1").encode("utf-8", replace: nil)
end
- 1. SQL錯誤:編碼「UTF8」無效的字節順序:爲0x00
- 2. Rails + Ruby 1.9「US-ASCII字節序列無效」
- 3. Ruby 1.9的多字節無效字符(UTF-8)
- 4. 無效的多字節字符(US-ASCII)使用Rails和Ruby 1.9
- 5. Ruby 1.9 -Ku,mem_cache_store和無效的多字節轉義錯誤
- 6. 在rails 2.3和ruby 1.9中無效的字節序列utf-8錯誤
- 7. Cassandra 1.2.5 - 無效的UTF8字節
- 8. Postgres插入錯誤 - 錯誤:編碼「UTF8」的無效字節順序:0x00
- 9. 紅寶石1.9 - 無效的多字節字符(UTF-8)
- 10. 無效字節序列(紅寶石1.9 +軌2.3.8 +的MongoDB + mongo_mapper)
- 11. Rails 3.2 with ruby 1.9.3 US-ASCII問題中的字節順序無效
- 12. PostgreSQL的:「無效的字節序列編碼‘UTF8’:只對錯誤
- 13. 紅寶石1.9 - 無效的多字節字符(US-ASCII)
- 14. ArgumentError:UTF-8中的字節序列無效
- 15. Postgresql PHP無效的字節序列編碼UTF8
- 16. PostgreSQL - Psycopg2 - copy_from - 用於編碼「UTF8」的無效字節序列:0x00
- 17. 藥劑 - Postgres的:編碼無效字節序列\「UTF8 \
- 18. 用於編碼「UTF8」的無效字節序列:0xed 0xa0 0xbd
- 19. PostgreSQL + PHP + UTF8 =用於編碼的無效字節序列
- 20. 我遇到無效UTF8字節序列的問題
- 21. ruby on rails語言問題「GBK中的字節序列無效」
- 22. UTF-8 Ruby中的無效字節序列
- 23. UTF-8中的Ruby無效字節序列
- 24. Ruby:檢查字節順序標記
- 25. Rails 3中,Heroku的 - PGError:錯誤:編碼 「UTF8」 無效的字節序列:
- 26. 網絡字節順序來承載java中的字節順序
- 27. 如何在參數化SQL查詢中避免無效的UTF8字節序列?
- 28. 「在EDB加載器中編碼爲」UTF8「:0x00」的無效字節序列
- 29. 錯誤:在pgadmin中插入用於編碼「UTF8」的無效字節序列
- 30. 寫入BYTEA字段 - 錯誤:用於編碼「UTF8」的無效字節序列:0x98
的東西,有可能打破字符,但保持串有效期爲其他庫: valid_string = untrusted_string.unpack( 'C *')包(「U *。 ') – 2011-08-06 07:17:32
有確切的問題,嘗試了相同的其他解決方案。沒愛。試過馬克的,但它似乎玷污了一切。你確定'U *''撤消了'C *'嗎? – 2011-10-24 03:05:15
不,它沒有:)我只是在一個webcrawler中使用它,在那裏我關心的第三方庫不會比我在這裏和那裏碰到的更多。 – 2012-11-29 09:48:16