2016-04-06 39 views
0

我試圖獲取某些網頁URI的HTML(即最初在頁面完成加載時看到的內容)。剔除所有錯誤檢查和假設靜態的HTML,它是一個單一的代碼行:在PHP中爲HTML頁面獲取OnLoad HTML/DOM

function GetDisplayedHTML($uri) { 
    return file_get_contents($uri); 
} 

這工作得很好靜態HTML,並且易於通過簡單的解析延長,如果頁面具有靜態文件依賴性/引用。因此,像<script src="XXX">, <a href="XXX">, <img src="XXX">, and CSS這樣的標籤也可以被檢測到,並且依賴關係在數組中返回,如果它們很重要的話。

但是,如何使用events/AJAX動態創建HTML的網頁呢?例如,假設網頁的HTML只是一個簡短的基於AJAX或OnLoad的腳本,它構建了可見的網頁?然後獨自解析將無法工作。我想我需要的是從PHP內部的一種方式,通過一些JavaScript引擎或瀏覽器打開和呈現http響應(即我們首先獲得的HTML),一旦它「穩定下來」,捕獲HTML(或靜態的DOM?),現在,這將是用戶真正看到的。由於這樣的網頁可能會不斷變化,我必須定義「穩定」(OnLoad或X秒後?)。我也不需要捕獲任何計時器或異步事件狀態(即「可能會在未來某個時間導致網頁更新的動作設置」)。我只需要足夠的DOM來表示用戶當時可以看到的靜態外觀。

我需要做什麼,以編程方式在PHP中實現這個功能?

+0

有預渲染服務,它將在頁面中進行代理,處理javascript,並提供呈現的html。許多使用JavaScript密集型應用程序的開發人員使用這些服務將呈現的內容輸出到Google和其他搜索引擎。這聽起來像你需要採取這樣的方法。這樣的事情可能是這樣的:https://github.com/prerender/prerender – skrilled

+0

我不想依賴第三方在線服務。但是我發現prerender是[PhantomJS](http://phantomjs.org)的一個基礎,它可以在很多平臺上運行,並且有使用示例。我猜可以在PHP代碼中運行,並可能解決這個問題?你是這麼認爲的嗎? – Stilez

回答

1

要用JS呈現頁面,你需要使用一些瀏覽器。 PhantomJS是爲這樣的任務而創建的。這裏是簡單的腳本與幻影運行:

var webPage = require('webpage'); 
var page = webPage.create(); 
var system = require('system'); 
var args = system.args; 

if (args.length === 1) { 
    console.log('First argument must be page URL!'); 
} else { 
    page.open(args[1], function (status) { 
     window.setTimeout(function() { //Wait for scripts to run 
      var content = page.content; 
      console.log(content); 
      phantom.exit(); 
     }, 500); 
    }); 
} 

它返回結果HTML到控制檯輸出。 您可以從控制檯像這樣運行:

./phantomjs.exe render.js http://yandex.ru 

或者你可以使用PHP來運行它:

<?php 
$path = dirname(__FILE__); 
$html = shell_exec($path . DIRECTORY_SEPARATOR . 'phantomjs.exe render.js http://phantomjs.org/'); 

echo htmlspecialchars($html); 

我的PHP代碼假設PhantomJS可執行文件在同一目錄下的PHP腳本。

+0

非常有幫助,謝謝!我會從PHP運行它,所以這個例子有幫助。有一件事會有所幫助 - 假設頁面內容應該被轉儲,並且PhantomJS在啓動後X秒或在OnLoad事件運行後X秒退出(如果頁面加載和事件代碼意味着應該轉儲時不清晰或者是一個緩慢的加載器,或者我必須決定一個時間限制的其他原因),我可以看到我可以將它提供給PhantomJS,但它比我擁有更多的專業知識 - 對這一點有什麼幫助? – Stilez

+0

我相信page.open回調是在onLoad事件之後運行的。您可以通過設置一些超時等待頁面JS運行。我用超時更新了我的答案,時間爲500毫秒。 –

+0

非常高興謝謝你!所以這個回調包括允許頁面加載時間「加一點」,這幾乎是完美的。我已經將它標記爲答案。一個問題,如果它很容易 - 如果頁面試圖訪問網關阻塞的URL/IP(一些最糟糕的跟蹤腳本被阻塞,因爲它們減慢了機器),然後onLoad將不會觸發,直到網絡超時〜30秒),使其變慢。任何事情都可以做到,無論頁面加載如何,它也不會等待比起5000ms更多的時間。 – Stilez