自定規(guī)則的AJAX網(wǎng)頁信息采集功能的設計
引 言
當前在數(shù)據(jù)量龐大的互聯(lián)網(wǎng)世界中,網(wǎng)絡上的信息存在諸多問題。虛假信息、重復信息、廣告干擾等這些信息往往都是冗余或者無用的信息,加上互聯(lián)網(wǎng)技術的發(fā)展與AJAX 技術的興起,許多站點從可維護性和增加用戶體驗的角度將數(shù)據(jù)與網(wǎng)頁分離,通過AJAX 從數(shù)據(jù)庫動態(tài)生成數(shù)據(jù),而有用的信息往往存在于這些數(shù)據(jù)中,但搜索引擎無法直接搜索到AJAX 網(wǎng)頁信息[1]。自定規(guī)則的動態(tài)網(wǎng)頁信息能夠采集AJAX 網(wǎng)頁信息,并且用戶可以自由選取網(wǎng)站并自定采集規(guī)則,功能垂直,目標專一,能夠高效且快速地獲取網(wǎng)頁信息。
1 AJAX網(wǎng)頁信息生成原理
據(jù)中國互聯(lián)網(wǎng)中心統(tǒng)計,當前中國的網(wǎng)站有百分之四十多都是動態(tài)網(wǎng)站,幾乎占據(jù)了中國互聯(lián)網(wǎng)的半壁江山,而日常人們主要通過搜索引擎來獲取自己感興趣的信息,搜索引擎的核心之一是網(wǎng)絡蜘蛛(Web Spider)。網(wǎng)絡蜘蛛通過給定的起始頁面按照一定的規(guī)則提取頁面中的鏈接,直到?jīng)]有鏈接,蜘蛛才停止提取[2]。這其中的過程僅僅解析了網(wǎng)頁的源代碼,卻沒有把網(wǎng)頁信息寫入網(wǎng)頁源代碼中,因此爬蟲收集的只是沒有加載動態(tài)信息的網(wǎng)頁資源。當用戶瀏覽動態(tài)網(wǎng)頁時,首先在瀏覽器的地址欄輸入網(wǎng)頁的URL,向對應的服務器發(fā)送請求獲取該 URL對應的頁面,當獲取到頁面時,此時并沒有獲取到網(wǎng)頁的信息,瀏覽器的JS(JavaScript)解析器會繼續(xù)解析寫在網(wǎng)頁中的JS 代碼,作為動態(tài)網(wǎng)頁,數(shù)據(jù)通過頁面中的JS 繼續(xù)向服務器請求數(shù)據(jù)庫中的數(shù)據(jù),而傳統(tǒng)的網(wǎng)絡蜘蛛并沒有執(zhí)行這些后續(xù)請求,蜘蛛的功能僅相當于瀏覽器的第一個請求網(wǎng)頁的動作,在瀏覽器中通過查看網(wǎng)頁源代碼可以看到一些AJAX 信息并沒有顯示在源代碼中,而網(wǎng)頁中能夠顯示信息, 正是由于瀏覽器中后續(xù)的JS 解析。該過程的原理圖如圖1 所示。
如圖 1 所示,在該網(wǎng)頁信息生成的過程中,只有當客戶端請求到頁面之后,再通過客戶端中的JS 解析器解析網(wǎng)頁中的JS 數(shù)據(jù)請求代碼,才會從數(shù)據(jù)庫請求數(shù)據(jù)并寫入頁面。
2 自定規(guī)則采集功能設計
根據(jù)前面所分析的原理可知,僅單純的使用一個 get 請求來獲取 AJAX 頁面中的信息在原理上是不可行的,因為服務器端并不能解析JS 代碼,只有在客戶端才能解析,服務器端只能夠將網(wǎng)頁原封不動地返回給客戶端,存在于網(wǎng)頁源代碼中的JS 數(shù)據(jù)請求并沒有運行。作為一套信息采集系統(tǒng),該系統(tǒng)的全部功能模塊必須都放在服務器環(huán)境中,只有通過一個可以完全解析網(wǎng)頁的引擎才能使服務器端解析JS 獲取網(wǎng)頁信息。經(jīng)過摸索和查找,認為JS 的開源工具包 PhantomJS 可以完成該項功能。可以將PhantomJS 引擎存放于服務器端,通過服務器端語言來調用,這里使用PHP 語言。
2.1 自定規(guī)則功能結構的設計
屬于一個網(wǎng)站的所有頁面的結構基本類似,網(wǎng)站與網(wǎng)站之間的結構可以完全不同,也可以類似,但網(wǎng)頁結構幾乎不可能完全一樣,即使存在輕微差別,也會導致一些信息的提取規(guī)則完全不同。因此一旦寫死了某一個網(wǎng)站的提取規(guī)則,隨著網(wǎng)站的改版,可能其中頁面的結構發(fā)生了變化,僅HTML 標簽名屬性發(fā)生變化就會導致抽取規(guī)則的改變,因此用戶自定規(guī)則能夠很好地解決問題[3-8]。提取信息的規(guī)則寫在JS 文件中, 除開 PhantomJS 函數(shù),用戶只需要寫提取網(wǎng)站信息的DOM 規(guī)則。在前臺設計一個用戶上傳規(guī)則和選取規(guī)則的功能,服務器端設定一個專門存放規(guī)則的文件夾,前臺能夠讀取用戶上傳的規(guī)則,從而完成目標頁面信息的提取。自定規(guī)則工作原理圖如圖 2 所示。
用戶寫入核心的DOM 規(guī)則上傳到規(guī)則庫。當用戶需要使用該規(guī)則時,前臺可以加載規(guī)則庫中的文件,通過選取指定的文件,服務器將文件名傳入PhantomJS 引擎中,接收網(wǎng)站的鏈接以目標網(wǎng)頁進行信息提取,返回信息經(jīng)處理后返回客戶端。
2.2 PhantomJS與PHP通信
服務器中存放一個 PhantomJS 可執(zhí)行文件, 稱其為PhantomJS 引擎, 該引擎通過命令窗口運行一個JS 為后綴的文件,該文件中寫入一些PhantomJS 的接口函數(shù)和網(wǎng)頁鏈接以及信息提取規(guī)則。作為單純的信息提取,JS 文件中的PhantomJS 接口函數(shù)是固定的,它們可以完成解析和加載網(wǎng)頁,使網(wǎng)頁內部的 JS 源代碼完全執(zhí)行。PHP 函數(shù)庫中存在一個 調用可執(zhí)行文件的函數(shù) exec()。利用該函數(shù)調用 PhantomJS 可執(zhí)行文件,PhantomJS 運行用戶自定規(guī)則的 JS 文件,從而 進行動態(tài)信息的提取。例如 exec("chcp 65001 && cd /d f :/ phantomJS/phantomjs-2.0.0-windows && phantomjs sample.js
{$url}",$arr,$i),該語句表示通過 phantomJS 執(zhí)行 sample. js 文件,傳入頁面的鏈接為 $url,返回的結果存入 $arr 中。 Sample.js 文件中的代碼如下:
根據(jù)該代碼可以提取圖 2 中的價格信息,將對應的 URL 寫入上面 exec 的 $url 中,得到圖 3 所示的結果,由圖 3 可知, 價格 5 799 能夠被正確提取出來。提取結果如圖 4 所示。

結 語
本文提出了一種能夠自定規(guī)則提取 AJAX 網(wǎng)頁信息功能的設計,通過測試能夠成功提取動態(tài) AJAX 網(wǎng)頁信息,相較于傳統(tǒng)的網(wǎng)絡蜘蛛,自定規(guī)則設計可以更好更貼合用戶需求來對指定網(wǎng)站進行信息提取,避免了虛假網(wǎng)站的干擾和重復信息的冗余。相較于傳統(tǒng)的dom 信息提取系統(tǒng),該信息提取功能加入了 PhantomJS 包,能夠提取傳統(tǒng)dom 無法提取的動態(tài)信息,功能得到了加強。