標記為濫用,心得紀錄(純感想與流程)

這是一件不太容易遇到的事情:「標記為濫用」。在別人家的大本營做不好的事情,又用別人家的搜尋引擎搜尋如何處理,又在別人家的部落格發這篇心得,也算久違之後難得有動力寫篇文章。

前情提要:JN編修了程式,這個程式是個報名系統。之前的報名系統,使用者有提及一個狀況:在尖峰時段,有部分人會遺漏掉回信或缺少資料。這個情況算是很常見的問題,當圖時有大量報名者送出,而大量回覆平行運算寫入,以至於同時讀寫到同一行(正常情況下是新送出的回覆會到新的最後一行),而最後只留下最新的一筆。

要解決這個問題,就要延遲寫入,避開多數回覆同時執行寫入。就JN所知,在有「佇列 queue」或「鎖 lock」兩種方式能處理這問題。然而沒有找到佇列指令,但是有發現鎖指令。於是在程式碼中加了鎖,就能達到非同步讀取。因為只有得到鎖的線程才能讀取,其他沒有鎖的就會等待直到拿到鎖。

然而,為了測試大量回覆送出是否會出現異常,JN一共用了五十筆送出,每個送出都上傳3MB大小的檔案。這次測試之後,就發現報名系統其實就是平行運算的問題。關鍵字就是「回覆缺失、大量短時間內」。之後JN把「鎖」寫進程式內,再以三十筆回覆測試之。
(JN所參考的寫法)

這次的結果,回覆都有被寫入資料表裡而沒有任何缺失,只是收到的順序不一定是照送出的順序。大功告成。就不再需要測試這種大量送出的狀況。

卻也釀成帳號「標記為濫用」。


「標記為濫用」是怎麼樣子呢?就是上傳的檔案會被標上一隻小旗子,這些有小旗子的檔案都是「標記為濫用」,被標記的檔案就無法給其他人查看,更無法建立副本。對於一般團隊,這個限制真的很麻煩,自己上傳的檔案都無法分享給別人看。更何況是非自然人的帳戶,大家共用的帳號被標記起來,豈不是許多資料就無法像平常般傳給同事們了。

雖然很麻煩,但另一方面,這一塊也是JN一直所擔心的地方。JN檢查之前的報名系統,便發現也一直提及「安全」的問題,但是請JN編修程式的人一點都不在意這一塊。「安全有比方便重要嗎?」「應該不會有人這樣做吧?」JN聽到的當下是很傻眼的,「被大量傳送攻擊」這個議題就輕易被忽視過去。只要被一次這樣攻擊,就會導致整個系統從此無法順利運作。更何況操作系統的又不是JN,出了甚麼狀況JN也不會有甚麼損失。

想一想就算了,反正寫多少也就多賺工錢,拿錢做事不要想太多,也不要做太多。

但是!對於異常流量的警示,那家公司真的十分厲害。JN欽佩這種會對於「安全」上做了很棒措施的公司,不像委託JN修改程式的人一點都不在乎「安全」這個問題。之前JN也測試過用程式去抓取一些資料,一下子就會被擋下來,對於想收集資料的人,這真的令人厭煩,但不過也就鎖IP,換IP就能繼續抓。但「標記為濫用」應該是鎖帳號,而且快一週了都沒有解鎖,也不知道多久後才不會有事,或是從此就背負一輩子。

也不知道甚麼時候才能解開「標記為濫用」。但是對於不太行的電腦操作者,又會給JN下怎麼樣的任性要求,一想到就會頭痛啊。

問卷的圖像辨識,opencv – python

有天,在中心辦完活動後,回收了一大堆的回饋單,目測有上百張左右。回饋單以人工辨識,費時費力,實在覺得很麻煩。填入回饋單的結果是個重複性高且技術性低的工作,以人力執行,時間都大多花在辨識以及騰入回答,若是交給電腦執行,這將會是秒殺的工作,而且十分準確不會誤看。

圖像辨識跟機器學習一直是JN很想嘗試的一塊,而且這兩塊正是未來的大趨勢,雖然以後人類的工作多半會被機器取代,不過人類就可以有比較多時間思考與享受生活,到時一個全新的社會型態會挑戰人們習慣的認知,你我都被這個時代潮流推著走。

問卷圖像辨識,是一個很好的應用。若為了讀問卷而買讀卡機有點太過於浪費讀卡機的效益,而且讀卡機也限制了問卷的形式,出問卷的人就不能隨心所欲的出問題。JN想要寫出一個,問卷格式能相當自由,同時讀取精度也相當準確的問卷圖像辨識程式。

關於圖像辨識,JN第一個就想到opencv這個處理影像的套件。在之前爬youtube的python教學影片,也有教人使用opencv去做辨識碼的破解。但是,JN很快就發現那教學影片對想要做的功能是勾不著邊的,於是只好進去opencv的官網教程慢慢修練功夫。

JN是用visual studio 2017,並且python環境選用anacoda。然後在「python環境」→「封裝」,搜尋「opencv」,找到「opencv – python」安裝,之後等待流程跑完要很久,這時可以去看個電視節目再回來!

終於等到流程跑完了,這時候就能引用cv2這個套件。JN很快就碰到了大問題,就是系統相容的問題。JN的桌電系統是win7,每當執行cv2裡面的一些函式,程式就會停止運作。接下來使用偵錯程式去找原因,幾次原因都指向「ntdll.dll」。ntdll.dll是一個系統檔案,JN檢查桌電的ntdll.dll檔案,並沒有問題或遺失。然而JN換成筆電,筆電系統是win10,在win10下跑python – opencv就沒有任何異常了。中心的電腦也是win10,一樣沒有問題。所以JN推論,

opencv – python,不適用windows 7作業系統執行。而window 10作業系統可以執行。
老實說,這個問題差點讓JN放棄了,現在也在心想是不是該把桌電換上win10,最後還是決定win7再戰10年!
每次看官網的教程,JN都覺得很簡潔,很多細節沒有寫出來,令JN我總要想很久。這次的opencv更是困難,好幾次JN完全複製官網的程式碼,結果執行時各種錯誤,真的很賭爛。除了官網之外,JN也看了很多中國論壇寫的教學,也推薦看官網不得領悟的人去查看看。
關於問卷辨識系統,其實就是要讓程式以圖像判斷每一選項的填寫情形,並且把判斷的結果輸出。圖像判斷是用官網教程的「Template matching」的功能,這功能用來一個模版圖樣(template)去搜尋另一圖片上相同的模版圖樣。其中有個耐人尋味的閥值(Threshold),閥值高會抓不到對的,太低又會抓到錯的,倒底該設多少才會有最高的精準度呢?這就讓機器學習去告訴你答案吧!
實際上,JN走的路程比理論事先想的的路還多好幾倍。核心運作的功能相當好寫,但是「精準度」及「效率」,就是個永無止境的課題。為了達到JN心中所想的精準度,這套問卷圖像辨識系統被重頭寫兩次。要怎麼讓Template matching能順利抓出所有圖案,機器學習要怎麼安排及應用才能輔助精準度提高,此外如果圖像處理太複雜,整個執行下來會太冗,效率很差(雖然還是會比人工快)。
JN心中所想的精準度是99%。雖然在寫出三次後,測試後,精準度達到99%(事實上跟人工辨識相當了),但是JN仍然覺得不夠,不夠的地方在於給某些嚴苛又機掰的圖像測試會失敗,此外機器學習並沒有完美容入進入整個運作中。
JN寫的問卷圖像辨識還有許多地方要改善與編寫,JN期望某一天,能在Android系統上推出,讓大學生還是XX中心都能普及使用,省下時間來去為了更美好的事物。


後續記事(2018.6.18)
結果不到一年,桌電也換成了win10。JN後來就沒有再改良問卷圖像辨識,因為實體問卷數據化的好壞,決定了圖像辨識的成功度,並不是機械學習、也不是參數設定能讓圖像辨識度成功。
輸入資料的品質好壞,才是最應該先把關的,花時間注意的。圖像辨識,相對只是件較不重要的事。如果不會圖像的概念,處理圖像的技巧,矯正圖像,規格化,之後做的圖像辨識就會有很大的侷限性。
一個程式到底要不要完成,要看它後續到底能換來多少好處。對於一百多份問卷,一個細心的人可以一次全對地填寫,但對程式來說,這樣樣本過少,會學習不到最佳狀況,即使讓這次的問卷學到全對(過度學習),接下來面對下一次的問卷,就會判斷得很失敗,這是可以預期的。
大概就是這樣的感悟,JN也就放棄了改良圖像辨識。

嘗試用Python爬蟲技巧抓混音音樂

這天JN在耍廢休息時瀏覽ptt時,又見到過去頗想收藏的音樂。比較可惜的是,音樂網站只有提供網路播放,並未提供下載按鈕。然而,JN堅信一點「只要能被人聽閱的影音,其檔案一定被下載進自己的電腦裡。」所以,JN相信,只要我能在網路上以正常方式聽閱的任何影音,絕對有方法給它給存下來。
根據之前學過的爬蟲技巧,第一步,先用chrome的Web Developer Tool(F12)並重新整理網頁後觀察。JN很快就發現了影片格式的檔案:mp4以及m4s。接著,打開其影音檔案來源網址,使用另存新檔的方式存下。
存下來的mp4具有正確的影音時間長度卻沒有任何音訊。m4s則為分割的許多片段,直接用影音播放器並不能播放,於是JN試著把副檔名改成mp4、mp3,亦得到同樣的結果:無法播放。
隨手求助google,打上「m4s 合併檔案」搜尋,不過搜尋的結果卻不是很滿意,前幾個結果內容所說的程式,從程式的官方網站看,卻得到程式碼,而不是直接能用並帶有介面的程式。不然就是被防毒軟體掃出有疑慮,最後找到的程式碼也並非JN所學過的程式語言。用英文搜尋也是差不多的答案。
不過雖然程式碼並非JN所學過的程式語言,但JN觀其架構是十分簡單的,其運作過程只是把mp4(開頭)以byte方式合併其他的m4s(片段),最後就能得到所想要目標影音檔案。如果是正常能播放的影音檔案,就能用剪接軟體。不過碰到byte合併的方式,寫程式碼就是最簡單的方法。
byte合併可以直接以字元提示命令去執行,但JN不是很熟這個,JN比較熟悉python,於是用python去寫。
當使用Web Developer Tool去看時,JN就發現影音片段(m4s)會隨時間下載後面的片段,並不會一開始就把全部的片段都下載完,這段於提升網頁瀏覽速度是很有幫助,不過卻苦了想直接下載一個完整檔案的人。觀察其片段的網址,各片段的網址取決於編號的不同,所以只需要改編號,就能抓到想要的片段。JN直接嘗試1000號片段,跑出結果404,只要超過片段數,就會抓到404網頁,然後看檔案大小就知道從哪一編號後的就是抓到404網頁。
要抓所有片段很簡單,只需要用迴圈產生各片段網址,然後用python的request套件去get各片段網址,得到「get的結果」,並且用python的shutil套件把「get的結果」存成m4s影音。這些技巧都是從網路教學的爬蟲影片學到的,JN在第一篇的python網誌有寫到從哪裡學到的。最後,JN當時所抓的片段有七百多個,每個平均90kb。
所要的檔案都齊了:開頭的mp4、所有的m4s片段,接下來就是要合起來了。
別忘了要以byte方式合併,JN用python內建的open函式,以wb的方式寫一個輸出檔案。程式碼如下。
AllFragments = open(output.mp4,’wb’)
接著其他的片段,也是以open函式以’rb’來讀取,然後以read得到其byte數據。接下來,照順序以mp4的byte數據、以編號順序片段的byte數據,寫進輸出檔案裡。這樣就完成以byte方式合併所有片段了。
最後,用播放器打開輸出檔案,能夠播放,而且也與網路上所聽到的相同。直接跳到最後十秒測試,也沒有缺少音訊。這就是JN所想要的影音檔了。
後記:
JN猜測,其實合併各片段的程式碼,應該在第一步的時候就已經抓到了。猜測是程式語言javascript去做這次JN用python做的事情。但只是JN的功力不夠深厚,挖掘經驗太淺,沒辦法第一時間撈出來。希望有一天記得要再好好地把這個程式碼給揪出來,而不靠自己閉門造車。
會講混音音樂是個提示,並不是指各網站的混音音樂。
這個程式碼可以繼續寫成音樂爬蟲,能夠爬下所有的音樂並且合併輸出。不過JN觀察,該網站應該有下載流量限制,想快速抓完音樂需要有點技巧。

臺鐵大誤點以及捲簾式快門

今天JN去考全民英檢中高級,考完後,跟朋友去棒壘球打擊場打球。那時看了一下火車時刻表,有班車晚了一百多分鐘。因為出門後就沒有機會看到新聞,所以並不知道臺鐵發生電線脫落的意外,於是就選擇到火車站等車,達成人生史上等最久的車。
看到大誤點,延誤一百多、兩百多分鐘就好像在叫賣一樣,隨便喊價。難得碰到,拍下來做個記錄好了。正當拿著手機去照的時候,發現手機螢幕的跑馬燈,竟然跟以下影片一樣。

實際上肉眼看到的不是這個樣子,肉眼看到的是全部都亮的,如(圖一)的照片。JN看到這個現象就知道為甚麼。之後月臺又來了一對母子,那個媽媽拿起手機想拍下來,也同樣看到這個現象,然後困惑地說為什麼會這樣子。再後面又有一對情侶檔,也個那個媽媽一樣,並不了解為什麼拍起來會這樣。

(圖一)

JN直接講答案,因為手機是捲簾式快門,而且跑馬燈是超過人眼能捕捉的速度閃爍。捲簾式快門,顧名思義,就是像捲簾那樣,按下快門後,一條條曝光,最後形成一張完整的照片。一條條掃過的瞬間很快,於是我們拿手機拍照時,通常不會察覺到。人眼看到,相當於全局快門,也就是所有畫面一次曝光成像,同時閃爍過快導致看起來就像恆亮,因此看跑馬燈就不有像相機這樣一條條的問題。

這是JN認為為什麼會這樣子的答案,不知道大家有沒有自己的答案呢?

(圖二)
對了,照我的推論來看,手機拍起來應該要像(圖二)才對,為甚麼我能拍出(圖一)呢?厲害一點的人應該已經看出來是怎麼拍的了,就是調長快門時間。只要增加曝光的時間,比閃爍的間隔久,就能拍出(圖一)跟人眼看到的差不多。

這個現象有沒有很有趣呢?下次在臺鐵月台等車時,也不仿讓同行的朋友看看這個現象,讓他們動腦筋吧!

2017.9.23 學習了一個月的python歷程

在八月中,參加歡送朋友的聚會,會後歸程,我向友人提出想要學習大數據的想法。之後處理完宿舍後,回到家,JN就開始尋找大數據的相關資訊。透過Google第一個找到的,「Weka」(官方網站)。

在簡單使用Weka過後,JN明白Weka是一套分析數據的軟體。這套軟體能夠找出各數據間的相關性,近而找出影響結果成敗的因素。但是!如果手上沒有資料,那就無法進行數據分析了。為了要取得一套可供分析的資料,於是JN找到了Python,想藉Python抓取到一份資料,裡面至少有上千筆的記錄,完成一輪無法透過人力逐一蒐集資料(如果人力允許,就用excel即可應付),必須得透過程式才能完成的數據分析。

在大四的時候,JN跟系上導師聊天,導師那時就跟我提過Python,雖然系上都用R跟SAS作數據分析,不過系上教的R實在是有夠無趣而不令人想學習。Python也有一套數據分析的套件。根據這一個月體驗過後,JN覺得Python是很棒的語言,當然也有很多使用Python進行開發,像是Google、FB等。

Python的優點是甚麼?更簡單更人性化的編寫方式。JN接觸過這其他幾種程式語言:C++、C#、Java、Javascript,JN發現越新的語言,在函式跟變數的定義上越簡單。JN接觸到了Python,變數不用先宣告,函式也不用指定輸入的變數類型,每句結束不用;(分號),而是用縮排,這也使得程式碼看起來整齊多。當然還有很多不一樣的地方,不一一敘述。

JN的開發環境是Visual Studio 2017,並安裝了Anaconda,然後在Visual Studio的python環境使用Anaconda去編寫。JN認為,程式語言得按教科書按部就班學習是很無聊的,光是一個變數加減就能寫三頁,然後一本書有上千頁,也不知道讀了那麼多指令能用在哪裡。

任務導向式的學習,對於解決問題有很大的幫助。因為要完成任務,所以必須要學會相關的指令,不然無法達成目標。於是JN先不急著抓下一份上千筆的資料,而是先依序慢慢學習抓資料。以下是JN的Python任務:

抓ptt表特版→抓ptt西斯版→抓dcard西斯版→抓食譜網的食譜→抓股市即時資料

這流程的任務的困難度是逐漸增加的。不過一開始,JN也不熟悉Python真正強大的地方,沒有看過任何Python書籍,對於完成任務要怎麼寫是毫無頭緒的。其實啟發JN能寫出網路爬蟲的,是看了這一個Youtube頻道(大數軟體有限公司),裡面有很多關於python爬蟲的影片,影片不長,內容精要,照著做就能順利抓下資料,是一個很好的範例去參考。看這影片教學,你不會學到其他沒有用到的東西,從影片學到的東西都是直取目的會用到的。

很快地,就能碰到爬蟲所要使用的指令與套件。對於JN這種沒有資歷的人,花上了好幾天的學習,才弄懂程式碼的運作方式,像是BeautifulSoup(BS)套件是能夠剖析HTML(HyperText Markup Language)。HTML編寫是用標籤為架構,瞭解HTML的架構的特性,用BS就能取出要的部分。

這篇網誌也不是Python教學,所以想學Python還是去看看影片或是書會比較能瞭解Python要如何使用。

到了現在,JN只有看了幾本書,不過都不是python的。對於初學者來說,以JN這種任務導向型的人,蠻推薦o’reilly的head first系列去看,因為書中每一章節的例子都是要解決問題,而且書中的程式碼難度不高,是很平易近人的。初學者不會一開始就被教材難度的門檻撞死,才能學到東西並繼續延伸,之後若有興趣就再去讀其他講說更深入的書籍。

我的Python學習歷程(補充)

1.在「抓ptt表特版」時,學到了BeautifulSoup套件、Request套件、Shutil套件(儲存圖片)、re套件(過濾字串)。

2.在「抓ptt西斯版」時,學到了Request中的session、post,os套件(創立資料夾與切換工作目錄)。

3.在「抓dcard西斯版」時,把之前所學到的精良化,節省程式碼,更瞭解網頁的運作模式,回傳資料的類型。

4.在「抓食譜網的食譜」時,學到了Pyodbc(把資料寫進資料庫)、SQL指令、以及資料類型。

5.精良化「抓ptt表特版」,學到了多線抓取,python不再按部就班的一篇篇文章進去抓取、退出再換下一篇。提高的抓取效率。

6.在「抓股市即時資料」時,學到了Selenium,它能模擬瀏覽器做動作。GTTS套件(使用google語音)、Pygame套件(播放聲音)。

忘記行李後的心情低落

在2017年8月11日晚上六點二十分到達台北車站,發現台鐵南下列車均發生了誤點,緣由是因為號誌故障,導致大部分的車都延遲了二十分鐘發車。
JN我看到月台上擁擠的人,就知道不妙了,原本要搭的車延遲了二十多分鐘,導致我還要站半小時才能搭到車。剛好有一班列車進站,只行駛到新竹,想說我要是搭這班到新竹,再轉到我本來要搭的車,這段空檔時間,我可以出站買杯手搖飲後爽快回家。
上車後,真的很擠,我知道會站很久,於是把行李袋放到置物架上。大約到了中壢有了位置坐,就坐了。很無聊地滑手機,查看待會要去新竹買甚麼手搖飲。終於到了這班車的終點站,踏出輕快的腳步下車,一種很久違的感覺,先看看我有多少空檔可以溜出新竹火車站。只有十幾分鐘,我覺得不行。
就繞了新竹火車站外圍一圈,然後想到了充電器,就想到充電器在行李袋,一個快步進站,車早已離去。我想起那班車到了新竹之後,就換成往北上行駛。只是進了車站後,就不想回到大廳去說明遺失物。想說到了竹南再說,順便買線材。
說到線材,去年換了手機,原本手機傳輸線就不適用,得換成Type-C的線材。原本有多買一條,但是接觸不良,我幹你老師咧,不到幾下就退役了,絕對是錢坑。原廠的Type-C線真的很耐用,因為續航力夠而一天就充一次飽飽就夠了,線一條就足夠應付了。但是,還是遲早得再買一條Type-C傳輸線備用,這我遲早就知道的。
充電器已隨著行李袋遠去,Type-C的線在手機界中,並不算普遍的。我總算不得不再買條Type-C的線,不然手機明天就沒有電了。查了一下手機店,不過出了火車站一下就看到了,進門直接說要買Type-C傳輸線,這個錢花得心疼卻是不得不花的。店員拿了雙條線一組的,報價說490。算了,就算知道買貴又怎樣,但極需的人是不得說不的,不多說掏錢買了。
終於等到家人來接我了,比預期晚了快一個小時才到家。手搖飲沒喝到、行李遺失了、又得花錢買了線材好維持我手機電力。真是禍不單行,JN替自己都覺得好難過。加上昨天的手機原廠耳機也壞一聲道,立刻再買一條來維持我平常用耳機的感覺,但這個壞是自然又加上不小心摧殘多次,JN覺得原廠耳機很耐用。這兩天,通訊周邊就噴掉一千。
在下竹南車站時,立刻去反應我的行李袋掉到哪個車次的車上。但是站務人員對於我的搭車模式無法理解,我知道車就在那班車上,但是他們還是按他們步調,重頭按部就班的推論出是哪班車,這沒啥關係,至少有推論到正確的結果。在到竹南站前,我有回想起行李內容物是甚麼,但是沒有想得完全,在他們詢問的時候,竟然忘記一樣很重要的東西沒說到,不過說到的都有中,應該不會覺得要把內容物全部說到才是失主吧,哈哈。之後就留下資料等通知了,之後的當晚都沒有台鐵的電話,先預想是直接協尋是沒有下文了,我看我要跑到基隆去照正常流程領了吧,唉唉唉。
雖然自己是不容易犯忘記東西的錯,偶爾難免會犯,不過犯的當下好像是命運逼得你一定要犯。讓人記憶完全回想不起來在哪裡,推論也找不出來,非常的奇妙。我的一本書就是這樣找不到了,那本書是從圖書館借來的,這樣的話,八成可能性要賠錢了事了。不過我對我的行李袋印象深刻,相信過幾天就能拿回手裡。但是那本遺失的書,只好認輸而賠吧,但這就又要花錢了。
心情低落,唉唉唉,覺得自己像一般人的時刻。QQ