2015-09-11 81 views
1

我下載pjscrape(運行引擎蓋下PhantomJS)完全填充的動態內容,而事實上,頁面查詢完全恢復填充的內容,包括動態內容。不幸的是,pjscrape只會發出JSON或CSV。我需要HTML。獲取與PhantomJS

使用PhantomJS孤單,我有這樣的腳本(調用我的-query.js):

var page = require('webpage').create(); 
page.open('http://www.sonoma.edu/calendar/groups/clubs.html', function (status) { 
    console.log("status: " + status); 
    if (status !== "success") { 
     console.log("Unable to access network"); 
    } else { 
     page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js", function() { 
      console.log("Got jQuery..."); 
      var fullyPopulatedContent = null; 
      page.evaluate(function() { 
       $(document).ready(function() { 
        fullyPopulatedContent = $("html").html(); 
       }); 
      }); 
      window.setTimeout(function() { 
       console.log(fullyPopulatedContent); 
      }, 10000); 
     }); 
    } 
    }); 

但這個邏輯不落fullyPopulatedContentpage.evaluate完成後。 IE,fullyPopulatedContent只是總是null

這似乎是,你會覺得PhantomJS會做出來的箱子免費這樣一個普通的應用。

任何線索如何讓這樣的查詢工作,當目標URL包含內容動態地通過Ajax/JavaScript或幀填充?如果涉及到框架,您是否也可以解釋PhantomJS如何瀏覽框架內容,因爲在線文檔和示例對該主題不太清楚。

回答

1

PhantomJS有兩個上下文。 page.evaluate()是提供對DOM /頁面上下文的訪問的唯一函數。該函數是沙箱,這就是爲什麼你需要明確地傳入和傳出數據。

另一個問題是$(...).ready()監聽的事件很可能在您撥打page.evaluate()內部的$.ready()之前觸發很久。如果這是你想要加載jQuery的唯一原因,那麼你不應該這樣做。

你可以簡單地等待時間的靜態量:

var page = require('webpage').create(); 
page.open('http://www.sonoma.edu/calendar/groups/clubs.html', function (status) { 
    console.log("status: " + status); 
    if (status !== "success") { 
     console.log("Unable to access network"); 
    } else { 
     window.setTimeout(function() { 
      console.log(page.content); 
      phantom.exit(); 
     }, 10000); // adjust time for every page 
    } 
}); 

問題是當然的,你可以很容易地確定該頁面是否是滿載。一般來說,好的方法是waitFor(來自示例的函數)出現像最終元素這樣的特定條件,或者至少x頁面中存在相同類型的元素。這通常通過使用document.querySelector()page.evaluate()的CSS選擇器完成。

另一種方法是計數請求的資源,完成資源的時候看到有不小的時間量的任何掛起的請求,並希望資源請求之間的時間適當選擇。

幀:

PhantomJS自動獲取(I)幀作爲頁面負載的一部分。雖然,他們可能會比主/主框架晚完成加載。這就是爲什麼你可能需要額外的等待期。

當你採取截圖與page.render()你會看到包括加載(或加載當前)幀完整的頁面。

由於框架是具有自己的文檔根的獨立文檔,因此當您嘗試使用page.content打印主/父頁面的頁面源時,PhantomJS不包括它們。您首先需要更改其上下文以打印其DOM表示。

您可以做到這一點的名稱(如果幀有一個名稱)或通過指數(取決於幀的當前(父)幀的數目)。爲此,使用page.switchToFrame()。然後,您可以使用page.frameContent檢索幀內容。由於您切換到了框架上下文,現在您可以執行之前在主框架中執行的所有交互操作,例如自由更改DOM或單擊東西。當你完成框架,然後你可以改回page.switchToParentFrame()

+0

我嘗試了幾次超時。在*全部*情況下,查詢的頁面永遠不會充滿動態內容。我收到了有關URL的HTML正文 - 沒有動態內容。你關於你列出的代碼? –

+0

PhantomJS可能不處理通過iframe元素填充的動態內容嗎? –

+0

當然是的,但是在切換之前你必須切換到childFrame,然後才能訪問它的DOM或使用'page.frameContent'。 iFrame內容在父/主框架中不可見。 –