關於PHP批量採集----採集小說站有感

概況:幫周同窗作小說採集作了有一段時間了。一開始是從其它網站的頁面上直接寫正則去採集,而後慢慢的轉爲採集別人提供的API。 ajax

環境:CENTOS+NGINX+PHP5.2.17。基於JIEQI小說管理系統。 數組

直接採集其它網站頁面的時候,主要改的是JIEQI自帶的採集系統,印象比較深的,是加上了判斷章節順序的功能,還修改了其它的「BUG」(呀,其它具體什麼來着,我如今都快忘了,作了很久了)。這回感觸比較深的是,是採集API。 服務器

背景:採集數十個小說站的API(目前有五個,預計有40,50個) 異步

設計:共用一個顯示頁面,邏輯分開處理。可批量採集,可單篇採集。 優化

上個圖:其中,兩個實體,是根據我須要的信息,本身定義的。爲何要規定這個實體(或者是接口),主要是由於,每一個API給的信息都是不同的,要統一後,才能操做。 網站

單篇採集 VS 多篇採集 spa

單篇採集相對比較簡單,想怎麼寫都行,問題不大。 .net

而多篇批量採集,此次寫了四個版本。 線程

V1:將全部的操做,寫在了同一PHP進程裏面。 設計

    優點:邏輯簡單,容易實現。

    缺點:PHP進程容易龐大,容易掛悼。

    問題:最大隻能設置5篇,並且,不能看到採集的過程。

V2:將全部的操做分開,用file_get_contents遍歷訪問。

    優點:相似「異步」採集,將全部操做分開到每一個進程,單進程不容易掛。效率很高。

    缺點:採集過程將產生N多個PHP進程,NGINX會出現504等錯誤。

    問題:如上述缺點,若是一做品的章節較多,在短期內(0.1S或更短)產生上百個HTTP請求,NGINX出現問題,服務器吃不消。

    改進:在PHP中加上sleep,致使NGINX不穩定,集中耗資源。偶爾還出現file_get_contents的錯誤。

V3:結合V1和V2,用JS作定時。

    思路:使用iframe,定時刷新採集的每一個頁面(V2),根據頁面返回信息,作下一步操做。即:循環設置iframe的SRC。

    優點:將採集時集中對服務器的壓力分散掉,章節按順序來入庫。

    缺點:採集的間隔時間,不太好設置。哪怕是根據iframe的返回值,再判斷,也要多加定時(採用父頁面定時刷新,定時抓取iframe的數據來判斷)。

    問題:setTimeout出各類問題,會出現沒法控制的狀況。由於JS也是單線程的。setInertval也同樣。

V4:結合前面三,主要改進是在V3的基礎上,再次分開。

    思路:再也不循環設置iframe的SRC,而是,新建N多個iframe。

    優點:能夠很輕鬆的控制時間(即:間隔多少S,打開新的iframe)。

    缺點:若前面的章節操做比較慢(即:好比說,第一章卡殼了,2S都尚未鏈接上採集的PHP的URL。而第二章,在第0.5S後,已經開始,且鏈接上了,那麼第二章就會在第一章以前入庫),這裏就涉及到一個章節的順序問題。還有,同上,第一章已經鏈接上了,但,操做特慢,2S才搞定;而第二章,字數少(或其它緣由),1S就搞定了,問題同上。

    問題:同上缺點所述,還有一個問題要注意。由於有些字段,必需要在採集完以後,更新表的。SO,採用了一個方法:就是子頁JS,調用父頁的JS的一個方法,在父頁中設置一個iframe(ajax或script同樣),訪問修正做品的URL。

    實用:果真,實用的時候,缺點所產生的問題已經出現了。

    修正:將章節排序的字段,作到和章節信息同樣,放到數組裏面,同步更新。這樣,哪怕第二章先入庫,但它的order,仍是2。第一章後入庫,其order爲1。在顯示時,仍是第一章在前面。問題解決。

    

    每一個採集站的API和模版都分開了,這樣的好處就是統一了接口,其它的自由發揮。作這個玩意,也被周同窗說了幾回,不過想一想,確實,一開始作的時候,沒有考慮這麼細,作得不夠好,看來,仍是經驗不夠啊。

    固然,採集的話,建議使用.net作成一個EXE。有向周同窗提,但他以爲更麻煩,也懶得從新來弄過。如今這個版本,夠用了,符合要求了。還有優化的地方繼續優化。

    此拋磚引玉,期待大牛們的指點。

相關文章
相關標籤/搜索