簡體   English   中英

使用javascript(phantomjs)導航/抓取hashbang鏈接

[英]Navigating / scraping hashbang links with javascript (phantomjs)

我正在嘗試下載幾乎完全由JavaScript生成的網站的HTML。 因此,我需要模擬瀏覽器訪問並且一直在使用PhantomJS 問題是,該網站使用hashbang網址,我似乎無法讓PhantomJS處理hashbang - 它只是不斷調用主頁。

該網站是http://www.regulations.gov 默認將您帶到#!home。 我嘗試使用以下代碼(從這里 )嘗試處理不同的hashbangs。

if (phantom.state.length === 0) {
     if (phantom.args.length === 0) {
        console.log('Usage: loadreg_1.js <some hash>');
        phantom.exit();
     }
     var address = 'http://www.regulations.gov/';
     console.log(address);
     phantom.state = Date.now().toString();
     phantom.open(address);

} else {
     var hash = phantom.args[0];
     document.location = hash;
     console.log(document.location.hash);
     var elapsed = Date.now() - new Date().setTime(phantom.state);
     if (phantom.loadStatus === 'success') {
             if (!first_time) {
                     var first_time = true;
                     if (!document.addEventListener) {
                             console.log('Not SUPPORTED!');
                     }
                     phantom.render('result.png');
                     var markup = document.documentElement.innerHTML;
                     console.log(markup);
                     phantom.exit();
             }
     } else {
             console.log('FAIL to load the address');
             phantom.exit();
     }
}

此代碼生成正確的hashbang(例如,我可以將散列設置為'#!contactus'),但它不會動態生成任何不同的HTML - 只是默認頁面。 但是,當我調用document.location.hash時,它會正確輸出。

我也嘗試將初始地址設置為hashbang,但是腳本只是掛起而不做任何事情。 例如,如果我將網址設置為http://www.regulations.gov/#!searchResults;rpp=10;po=0 ; po http://www.regulations.gov/#!searchResults;rpp=10;po=0則腳本會在將地址打印到終端后掛起,並且什么也沒發生。

這里的問題是頁面的內容是異步加載的,但是你希望它在加載頁面后立即可用。

為了抓取異步加載內容的頁面,您需要等待刮到您感興趣的內容已加載。 根據頁面的不同,可能會有不同的檢查方式,但最簡單的方法是定期檢查您希望看到的內容,直到找到它為止。

這里的技巧是找出要查找的內容 - 在加載所需內容之前,您需要在頁面上不存在的內容。 在這種情況下,我為頂級頁面找到的最簡單的選項是手動輸入您希望在每個頁面上看到的H1標簽,並將它們鍵入哈希:

var titleMap = {
    '#!contactUs': 'Contact Us',
    '#!aboutUs': 'About Us'
    // etc for the other pages
};

然后在您的成功塊中,您可以設置定期超時以在h1標記中查找所需的標題。 當它出現時,您知道可以呈現頁面:

if (phantom.loadStatus === 'success') {
    // set a recurring timeout for 300 milliseconds
    var timeoutId = window.setInterval(function () {
        // check for title element you expect to see
        var h1s = document.querySelectorAll('h1');
        if (h1s) {
            // h1s is a node list, not an array, hence the
            // weird syntax here
            Array.prototype.forEach.call(h1s, function(h1) {
                if (h1.textContent.trim() === titleMap[hash]) {
                    // we found it!
                    console.log('Found H1: ' + h1.textContent.trim());
                    phantom.render('result.png');
                    console.log("Rendered image.");
                    // stop the cycle
                    window.clearInterval(timeoutId);
                    phantom.exit();
                }
            });
            console.log('Found H1 tags, but not ' + titleMap[hash]);
        }
        console.log('No H1 tags found.');
    }, 300);
}

上面的代碼適合我。 但是如果您需要搜索搜索結果,它將無法工作 - 您需要找出一個可以查找的標識元素或文本,而無需提前知道標題。

編輯 :此外,看起來最新版本的PhantomJS現在在獲取新數據時觸發onResourceReceived事件。 我沒有研究過這個,但你可能能夠將一個監聽器綁定到這個事件來達到同樣的效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM