HTML + nokogiri 解析編碼問題(清除非 UTF-8 字元)


#1

前輩們好,晚輩使用 Nokogiri 把一個網站的內容轉成所需文件的過程中,碰到轉出成亂碼的問題
看似都是一樣的內容,但有時轉出正常,有時亂碼,請問是因為我忽略什麼細節嗎?

使用 Script: https://github.com/leo424y/nokogiri-encode-issue/blob/master/lyrics.rb

轉出正常:https://github.com/leo424y/nokogiri-encode-issue/blob/master/lyrics/340518996-叫阮的名.txt
來源 html 正常:https://github.com/leo424y/nokogiri-encode-issue/blob/master/340518996-叫阮的名.html

轉出變亂碼:https://github.com/leo424y/nokogiri-encode-issue/blob/master/lyrics/340518997-黃昏嶺.txt
來源 html 正常:https://github.com/leo424y/nokogiri-encode-issue/blob/master/340518997-黃昏嶺.html


#2

因為 nokogiri 會誤判 HTML 的 encoding,因為他會去讀 html 內的 language …

不過你的問題主因不是這個,而是該 HTML 沒照規矩來 … 有包含不是 UTF-8 的字元就是

給你一個卍解,類似這樣的

unknow_html.encode!('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')

就會全掃描,然後刪除非 UTF-8 字元,才另外丟給 nokogiri 去做 parse 應該就好了才是,後續 UTF-8 處理也應該都不會遇到問題

然而這題後續我應該會全部用 regex 自幹唄,而非超級肥大的 nokogiri,不過這邊其實還滿累的懶得細寫,大概給個提示,先切割出想要的內容,而非全數過濾

<div id="content_all" # 過濾起點(需包含自己)
<ins class="rmax"     # 過濾終點(不包含自己)

然後刪除裡面的 HTML tag 類似

dirty_html = %Q%<p style="margin: 0px 0px 6px; display: block; color: #141823; font-family: helvetica, arial, sans-serif; font-size: 15px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20.7px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: #ffffff;"><span style="font-size: 18pt; font-family: 標楷體;">《TITLE》NAME</span><br><span style="font-size: 18pt; font-family: 標楷體;">作者:昨天</span><br><span style="font-size: 18pt; font-family: 標楷體;">--------------------------------</span></p>%

# 語意,使用 < > 內包含任何不是 > 的字元來做 Array 切割,並把空字串移除
dirty_html.split(/<[^>]+>/).delete_if{|i|i.empty?}

#=> ["《TITLE》NAME", "作者:昨天", "--------------------------------"]

會不會瞬間清爽些?,之後就是挑 array 的內容而已了 … 當然你的 split 可以跑很多次,甚至用 replace 類似增加一些 flag 來方便取值就是

這邊修正文章標題方便搜尋,以上

PS:版權物記得修正後才丟到 github 上面去哩