2013年1月8日 星期二

心得:檢索 PTT 的資料


我所撰寫的一個小玩具 =口=

前言


近期因為新專案的關係,需要嘗試去分析 PTT 特定看板的資訊
於是我陸陸續續撰寫了一些小程式:例如「推文分析器」、「發 P 幣機」、「PTT 尋寶機」
本文將針對「PTT 尋寶機」的開發,分享自己的心得! 以下先簡要的列出一些我對 PTT 的觀察:
  • PTT 的看板與文章,其實都有對應的 Web 網頁 (兩者之間有時間上的誤差)
  • 每篇文章的 Web 網頁中 <pre> … </pre> 之間的內容就是文章原文
  • 每篇文章的 Web Url 都不重複
  • PTT 的 Web 介面,可接受 1~2 秒間隔的 query 頻率(我沒有 try 到底線)
  • PTT 的看板有文章數限制,對應到 Web 網頁的話,大約有 900 頁左右(頁數或變動)
  • 透過 PTT 的 Web 介面連到已刪除的文章時,伺服器會回噴 404
  • PTT 上的控碼跑到 Web 網頁會呈現亂碼,壞掉!
  • 因為有「修文」的情況,所以文章的內文格式會「非、常、不、固、定」

心得


而在製作 「PTT 尋寶機」的實務上,我的心得為:
  • 我採取透過 Web 介面檢索文章,並沒有使用 telnetlib 透過 telnet 進行檢索(懶惰!)
  • 我並沒有使用 Scrapy 來協助抓取文章,而選擇自幹
    • 時間有點趕,沒空玩新玩具了 Orz
    • 加上我之前其實有寫過一些 Checkers 去鎖定交易文 … (爆!)
  • 推薦使用老字號的 httplib2 … 雖然我覺得他也有些小問題 Orz
    • 如果是抓取一般「正常的英文」網頁,其實我推薦使用 pyquery,支援直接填入 Url 當參數,然後就可以使用類似 jquery 的語法直接取得內容,方便度最高
    • 如果是抓取一般「正常的各國」網頁,其實 requests 寫起來很順手,讀取抓到的值時還會根據 header 自動做 decode 的動作
    • 我會建議使用 httplib2 是因為 PTT 的 Web 網頁編碼為 Big-5 ,且可能包含一些壞掉的控碼字元。因此,無論在做 decode 或 encode 時,都必須要手動加上 "ignore" 的選項,不然一遇到那些壞掉的字元就會噴出 exception … 。而 pyquery, requests 在使用上較為不方便(恩 … 後者也是支援讀取 socket 的 raw data 啦 … ),所以我就繼續使用 httplib2 了。( 我猜測 Scrapy 應該會對這種包含壞掉的字元的資料來源有處理的函式?)
  • 對於 parse data 而言:
    • pyquery 很方便,一句話就可以從網頁中抓出文章內容:
      • article = d("div#mainContent div pre").text() #possible be None
    • 對於之後文章的 parsing 我採用「硬幹」 + 「regular expressions」,其實如果後者強的話,就一切都沒問題了 …
  • 對於資料庫文章與 PTT Web 介面文章的同步而言,我採用懶人政策:
    • 每天看看最近 100 篇文章有沒有變動
    • 當有人要下載指定文章時,我才會將該文章同步到最新狀態

補充


資料庫我使用 mongodb,因為我常常亂改欄位(攤手),反正就一個極簡單 collection 而已
我並沒有使用專業檢索用的套件去分析文章,抓出關鍵字等等
我僅只是將資料庫內的文章做一些社交上的簡單統計
然後開了 nginx + gevent + bottle 的簡單組合提供 Web 介面
就完成小玩具了!(其實迴響還不錯 XD)

有趣(發人省思?)的社交分析

過程中,技術困難點大概還是在抓資料這一件事情
雖然我前端也卡了不少時間 … ( 囧rz 我不會寫前端啊啊啊
我是用 google 寫的啊
效能的話,我則是完全沒有優化 XDDDD
玩具的目的很簡單,就只是協助板友備份文章、以及提供查詢自己的資料
以使用率來看,不會有讓伺服器有什麼負擔的可能性
兩天的使用情況是不重複訪客 800 人瀏覽(畢竟是耳機、音響還算小眾市場)
總之,寫個小玩具,能讓我多摸到一些 python 的 module 及被強迫摸前端的東西
然後又能創造出一些價值給板友、鄉民
也算是皆大歡喜了!

新版的個資法實在非常嚴厲
各位如果有撰寫相關程式請務必小心 Orz
雖然我自認此服務,不營利、不為蒐集特定對象而寫且純粹出於善意
但是我還是願意提供反檢索功能 (目前是沒有人跟我說他不要被檢索啦 … )
歡迎有興趣的大大與我一起交流相關技術 ~~

-----------------------------------------------------------------
2014.05.28 本文補充說明:

由於 ptt 的 web 版在 2013 年有多次的改版
所以本文內容已經不適用現在的情況
只能當做是一個記錄

目前 ptt 的 web 版已經是輸出 utf8 編碼的內容
且作者、標題、推文等等資訊都已經被存放在特定的 xpath 路徑之內
所以可以用  pyquery 等套件,用類似 jquery 的方式輕鬆取得內容

又,上述說明了這麼多
其實強者我學長 c3h3 已寫好 crawler 且 open source
需要的朋友請取用!

https://github.com/c3h3/PlaYnlp-Corpus/tree/master/crawlers/ptt_crawler


沒有留言:

張貼留言