|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2006-07-14, 12:35 AM | #1 |
榮譽會員
|
軟體 - CMD與Curl雙劍合璧:自動合併多頁主題
CMD與Curl雙劍合璧:自動合併多頁主題
現實需求 當遇到長串經典的討論帖; 當看到分多頁的軟件教程; 當發現讓人愛不釋手的連載小說的時候。 如何儲存這些有很多分頁的內容就成為了一件冗雜而又枯燥的機械勞動。 無論是手工複製還是依靠軟件儲存,都需要大量的人為干預,這是身為智慧生物的我們所不能容忍的。 既然電腦的出現就是替代人進行一些繁複的工作的,那為什麼不把盡可能多的工作扔給它們呢? 可惜豆腐目前還沒有發現一款軟件可以滿足我的要求,既然沒有現成的可用那就自己動手吧。 思路分析 要解決一個問題必須先有一個環境,畢竟一個方案不可能通吃所有問題。我們就先設問題是要合併論壇中常見的多頁主題。 要合併一個多頁主題,我們首先得獲取這個主題的每一個分頁的內容,這種重複性的工作讓機器來做是再適合不過的了。 其次我們需要分辨用戶貼出的內容從哪裡開始,在哪裡結束。這部分第一次需要人來完成,後面的就交給機器吧。 最後我們需要獲取我們需要的內容並把它重新組織起來產生最終的成果,這同樣只需機器就可以很好的完成。 只要我們滿足了上面三點,我們就可以把自己從重複勞動中解救出來做其它的事情了。 解決方案 由於高階語言需要專門的學習和配套的軟件,這無形提高了應用的難度,最終豆腐選擇了用CMD命令行來完成這個工作。 當然,CMD命令中是沒有獲取網頁內容的功能的,我們還需要Curl這個強大的命令行工具來助我們一臂之力。 我們就以合併CCF精品技術論壇的MPlayer 2006-03-03 K&K 更新在 992 樓為例,順著剛才的思路來一步步嘗試以達到最終的Goal。 網頁抓取 在Curl的幫助下,我們可以輕鬆的通過命令行來抓取我們想要的網頁: CODE: curl -o tmp1.txt http://bbs..net/bbs/showthread.php?t...9&page=1&pp=15 [Copy to clipboard] 這樣我們就把該主題第一頁的內容儲存在了tmp1.txt文件中。 對於某些需要檢測瀏覽器訊息的網站,我們可以用 CODE: -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" [Copy to clipboard]來偽裝成IE瀏覽器。 對於需要使用cookies的網站,我們可以用 CODE: -D cookie1.txt [Copy to clipboard]來儲存cookies,用 CODE: -b cookie1.txt [Copy to clipboard]來讀取cookies。 對於防盜鏈的網站,我們可以用 CODE: -e "http://bbs..net/" [Copy to clipboard] 來偽裝成從某個相關聯接進入的。 再與CMD中強大的 FOR 命令和變數相結合,加上人類的小小智慧,就可以打造出自動抓取該主題的全部內容的腳本。 分析該主題的URL,我們可以知道 page= 表示頁數,這為自動化處理提供了基礎,同時我們知道該主題有73頁,最終的抓取腳本如下: CODE: @echo off setlocal ENABLEDELAYEDEXPANSION set last=1 for /l %%i in (1,1,73) do ( echo %%i curl -b cookie!last!.txt -D cookie%%i.txt -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -e "http://bbs.et8.net/bbs/showthread.php?t=634659^&page=!last!^&pp=15" -o tmp%%i.txt http://bbs.et8.net/bbs/showthread.php?t=634659^&page=%%i^&pp=15 set /a last=%%i-1 ) copy tmp*.txt temp.txt del cookie*.txt del tmp*.txt endlocal [Copy to clipboard] 將上面腳本儲存為 grab.cmd 執行後我們就的到了儲存了該主題全部73頁內容的 temp.txt 文件。 內容分析 由於CMD字元處理的問題,我們先把 temp.txt 另存為 ANSI 編碼。 分析單頁的內容後豆腐發現該論壇程式在用戶內容開始之前有一個每頁唯一的 , 而在結束的時候有一個同樣唯一的 ,這正是我們所希望找到的可以作為標誌位的地方。 文本處理 由於 FOR 命令一次只能以同樣的規則處理一行的內容,於是豆腐便採用 FOR 嵌套的方式來處理整個大文件。 先用 CODE: for /f "delims=" %%i in (temp.txt) do ( echo %%i >tmp.txt ) [Copy to clipboard]將 temp.txt 的內容一次一行地寫入 tmp.txt。 再套用另一個 FOR 來處理 tmp.txt 的一行。 標誌設置 我們可以通過 FOR 的 delims= 和 tokens= 參數來分割和儲存一行的內容 我們用 CODE: for /f "tokens=1-3 delims== " %%j in (tmp.txt) [Copy to clipboard]參數設定以 ""、"-"、"="、" "來分割一行, 並把分割後的前三段內容存入 %%j %%k %%l 三個變數中。接著我們用 if 語句來判斷這三個變數是否符合設置標誌位的條件: CODE: if "%%j"=="div" if "%%k"=="id" if %%l=="posts" set flag=1 if "%%j"=="start" if "%%k"=="content" if "%%l"=="table" set flag=0 [Copy to clipboard] flag=1 代表用戶內容開始,flag=0代表用戶內容結束。 內容剪裁 由於CMD命令行處理的限制,HTML中的註釋開始符號 "CODE: for /f "tokens=1-8 delims=" if not "%%s"=="-->" if not "%%r"=="-->" if not "%%q"=="-->" if not "%%p"=="-->" if not "%%o"=="-->" if not "%%m"=="ECHO" if !flag!==1 echo %%i >>new.htm) [Copy to clipboard] 同時,我們也完成了把開始標誌位後的內容存入 new.htm 的工作。 最終腳本 CODE: @echo off setlocal ENABLEDELAYEDEXPANSION set flag=0 for /f "delims=" %%i in (temp.txt) do ( echo %%i >tmp.txt for /f "tokens=1-3 delims== " %%j in (tmp.txt) do ( if "%%j"=="div" if "%%k"=="id" if %%l=="posts" set flag=1 if "%%j"=="start" if "%%k"=="content" if "%%l"=="table" set flag=0 for /f "tokens=1-8 delims=" if not "%%s"=="-->" if not "%%r"=="-->" if not "%%q"=="-->" if not "%%p"=="-->" if not "%%o"=="-->" if not "%%m"=="ECHO" if !flag!==1 echo %%i >>new.htm ) ) ) del tmp.txt endlocal [Copy to clipboard] 儲存腳本為 merge.cmd 執行後得到合併出的 new.htm 文件就是該主題全部1083帖的內容。 優化改進 該腳本只完成了抓取文本內容的工作,我們還可以通過判斷 IMG 元素來找到圖片內容, 並把 src 內容後面的路徑補完成完整路徑,就可以正確顯示出內容中的圖片。 後記總結 CMD和Curl相結合可以完成很多批量的複雜工作,雖然第一次多花點時間,但之後就可以方便的使用了。 該腳本可以順利抓取合併CCF技術論壇的任意主題以及部分基於vBulletin的論壇,但對於其它論壇還需要分別修改才可使用。 本文為chenke_ikari原創,首發於豆腐的簡陋小屋 本文采用Creative Commons 署名-非商業性使用-相同方式共享 2.5 China 許可協議 進行許可 |
__________________ |
|
送花文章: 3,
|