gpt4 book ai didi

javascript - 使用 Phantomjs 抓取 React 站点

转载 作者:太空宇宙 更新时间:2023-11-04 03:29:12 24 4
gpt4 key购买 nike

我正在抓取一个使用 React 组件的网站,在 Nodejs 中使用 PhantomJS。

这样:https://github.com/amir20/phantomjs-node

这是代码:

phantom.create().then(ph => {
_ph = ph;
return _ph.createPage();
}).then(page => {
_page = page;
return _page.open(url);
}).then(status => {
return _page.property('content');
}).then(content => {
console.log(content);
_page.close();
_ph.exit();
}).catch(e => console.log(e));

问题是 react 内容没有渲染,它只显示:<!-- react-empty: 1 -->"实际的 react 组件应该加载到哪里。

如何废弃渲染的 react 组件?我最初从纯 Node 请求解决方案切换到 PhantomJS 来解决这个问题,但现在我陷入了困境。

<小时/>

更新:

所以我还没有真正的解决方案。我切换到 NightmareJS ( https://github.com/segmentio/nightmare ),它有一个很好的 .wait('.some-selector')函数,它等待指定的选择器被加载。这解决了我动态加载 react 组件的问题。

最佳答案

我认为您应该在页面加载后等待在页面上呈现 react 元素。下面是使用 Q Promise 的等待函数的示例。该函数返回一个 promise 并每 50 毫秒检查一次页面状态。如果达到所需的页面状态,该函数就会解决 promise 。在超时的情况下,该函数将拒绝 promise 。

var phantom = require('phantom');
var Q = require('q');
var _ph, _page, _outObj;
var url = 'https://tech.yandex.ru/maps/jsbox/';

phantom.create().then(ph => {
_ph = ph;
return _ph.createPage();
}).then(page => {
_page = page;
return _page.open(url);
}).then(status => {
console.log(status);
return waitState(textPopulated, 3);
}).then(() => {
return _page.property('content');
}).then(content => {
console.log(content);
_page.close();
_ph.exit();
}).catch(e => console.log(e));

function textPopulated() {
return _page.evaluate(function() {
var layer = document.querySelector('.ace_text-layer');
return layer && layer.childElementCount;
}).then(function(childElementCount) {
console.log('childElementCount: ' + childElementCount);
return childElementCount > 0;
});
}

function waitState(state, timeout) { // timeout in seconds is optional
console.log('Start waiting for state: ' + state.name);

var limitTime = timeout * 1000 || 20000;
var startTime = new Date();

return wait();

function wait() {
return state().then(function(result) {
if (result) {
console.log('Reached state: ' + state.name);
return;
} else if (new Date() - startTime > limitTime) {
var errorMessage = 'Timeout state: ' + state.name;
console.log(errorMessage);
throw new Error(errorMessage);
} else {
return Q.delay(50).then(wait);
}
}).catch(function(error) {
throw error;
});
}
}

关于javascript - 使用 Phantomjs 抓取 React 站点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40440763/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com