首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用javascript导航/抓取hashbang链接(phantomjs)

使用javascript导航/抓取hashbang链接(phantomjs)
EN

Stack Overflow用户
提问于 2011-06-21 00:04:06
回答 1查看 3.2K关注 0票数 9

我正在尝试下载一个几乎完全由JavaScript生成的网站的超文本标记语言。因此,我需要模拟浏览器访问,并且一直在尝试使用PhantomJS。问题是,该站点使用的是hashbang URL,而我似乎无法让PhantomJS处理该hashbang --它只是一直在调用主页。

该网站为http://www.regulations.gov。默认设置会将您带到#!home。我尝试使用以下代码(来自here)来尝试和处理不同的hashbang。

代码语言:javascript
复制
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 (例如,我可以将hash设置为'#!contactus'),但它不会动态生成任何不同的HTML--只生成默认页面。然而,当我调用document.location.hash时,它确实正确地输出了。

我还尝试将初始地址设置为hashbang,但随后脚本就挂起了,什么也不做。例如,如果我将url设置为http://www.regulations.gov/#!searchResults;rpp=10;po=0,那么在将地址打印到终端之后,脚本就会挂起,并且什么都不会发生。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-25 03:29:24

这里的问题是,页面的内容是异步加载的,但您希望页面加载后它就可以使用。

为了抓取异步加载内容的页面,您需要等待抓取,直到您感兴趣的内容加载完毕。根据页面的不同,可能会有不同的检查方法,但最简单的方法是定期检查您希望看到的内容,直到找到为止。

这里的诀窍是找出要查找的内容--您需要一些在加载所需内容之前不会出现在页面上的内容。在这种情况下,我为顶级页面找到的最简单的选择是手动输入您希望在每个页面上看到的H1标记,将它们键入散列:

代码语言:javascript
复制
var titleMap = {
    '#!contactUs': 'Contact Us',
    '#!aboutUs': 'About Us'
    // etc for the other pages
};

然后,在成功块中,您可以设置一个重复超时,以便在h1标记中查找您想要的标题。当它出现时,您就知道可以呈现页面了:

代码语言:javascript
复制
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);
}

上面的代码适用于我。但是,如果你需要抓取搜索结果,它就不会起作用--你需要找出一个识别元素或文本,你可以在不需要事先知道标题的情况下进行查找。

编辑:另外,看起来newest version of PhantomJS现在在获得新数据时会触发一个onResourceReceived事件。我还没有深入研究过这一点,但您也许能够将侦听器绑定到此事件以达到相同的效果。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6414152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档