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

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