62

我正在寻找一个请求网页的示例,等待 JavaScript 呈现(JavaScript 修改 DOM),然后抓取页面的 HTML。

这应该是一个简单的示例,具有明显的 PhantomJS 用例。我找不到一个像样的例子,文档似乎都是关于命令行使用的。

4

6 回答 6

45

根据您的评论,我猜您有两个选择

  1. 尝试找到一个 phantomjs 节点模块 - https://github.com/amir20/phantomjs-node
  2. 将 phantomjs 作为节点内的子进程运行 - http://nodejs.org/api/child_process.html

编辑:

phantomjs 似乎建议将子进程作为与节点交互的一种方式,请参阅常见问题解答 - http://code.google.com/p/phantomjs/wiki/FAQ

编辑:

用于获取页面 HTML 标记的示例 Phantomjs 脚本:

var page = require('webpage').create();  
page.open('http://www.google.com', function (status) {
    if (status !== 'success') {
        console.log('Unable to access network');
    } else {
        var p = page.evaluate(function () {
            return document.getElementsByTagName('html')[0].innerHTML
        });
        console.log(p);
    }
    phantom.exit();
});
于 2012-04-02T14:20:58.443 回答
8

使用 v2phantomjs-node处理后的 HTML 非常容易打印。

var phantom = require('phantom');

phantom.create().then(function(ph) {
  ph.createPage().then(function(page) {
    page.open('https://stackoverflow.com/').then(function(status) {
      console.log(status);
      page.property('content').then(function(content) {
        console.log(content);
        page.close();
        ph.exit();
      });
    });
  });
});

这将显示输出,因为它会使用浏览器呈现。

2019年编辑:

您可以使用async/await

const phantom = require('phantom');

(async function() {
  const instance = await phantom.create();
  const page = await instance.createPage();
  await page.on('onResourceRequested', function(requestData) {
    console.info('Requesting', requestData.url);
  });

  const status = await page.open('https://stackoverflow.com/');
  const content = await page.property('content');
  console.log(content);

  await instance.exit();
})();

或者如果你只是想测试,你可以使用npx

npx phantom@latest https://stackoverflow.com/
于 2016-03-15T18:26:58.740 回答
4

过去我使用过两种不同的方法,包括查询 Declan 提到的 DOM 的 page.evaluate() 方法。我从网页传递信息的另一种方式是从那里将其吐出到 console.log() ,并在 phantomjs 脚本中使用:

page.onConsoleMessage = function (msg, line, source) {
  console.log('console [' +source +':' +line +']> ' +msg);
}

我可能还会在 onConsoleMessage 中捕获变量 msg 并搜索一些封装数据。取决于你想如何使用输出。

然后在 Nodejs 脚本中,您必须扫描 Phantomjs 脚本的输出:

var yourfunc = function(...params...) {
  var phantom = spawn('phantomjs', [...args]);
  phantom.stdout.setEncoding('utf8');
  phantom.stdout.on('data', function(data) {
    //parse or echo data
    var str_phantom_output = data.toString();
    // The above will get triggered one or more times, so you'll need to
    // add code to parse for whatever info you're expecting from the browser
  });
  phantom.stderr.on('data', function(data) {
    // do something with error data
  });
  phantom.on('exit', function(code) {
    if (code !== 0) {
      // console.log('phantomjs exited with code ' +code);
    } else {
      // clean exit: do something else such as a passed-in callback
    }
  });
}

希望对一些人有所帮助。

于 2012-05-31T20:21:08.190 回答
3

为什么不直接使用这个?

var page = require('webpage').create();
page.open("http://example.com", function (status)
{
    if (status !== 'success') 
    {
        console.log('FAIL to load the address');            
    } 
    else 
    {
        console.log('Success in fetching the page');
        console.log(page.content);
    }
    phantom.exit();
});
于 2013-12-18T16:07:38.217 回答
1

延迟更新以防有人偶然发现这个问题:

我的一位同事在 GitHub 上开发的一个项目正是旨在帮助您做到这一点:https ://github.com/vmeurisse/phantomCrawl 。

它仍然有点年轻,它肯定缺少一些文档,但提供的示例应该有助于进行基本的爬网。

于 2013-06-26T16:10:54.670 回答
1

这是一个旧版本,我使用运行 node、express 和 phantomjs 将页面保存为 .png。您可以相当快地对其进行调整以获取 html。

https://github.com/wehrhaus/sitescrape.git

于 2014-04-26T03:18:32.117 回答