[英]Nightmare.js screenshot buffer length 0
我正在運行一個nightmare.js腳本,我試圖在頁面上截取多個元素。
捕獲的第一個元素很好,但是折疊下方的每個其他元素都以零長度捕獲。 我正在努力調試這個問題。 任何幫助都會非常感激。
基本上,此腳本遍歷頁面並選擇頁面上與選擇器匹配的所有元素。 然后,使用async
收集響應並返回對象緩沖區。 問題是折疊下方的元素沒有截屏(緩沖區長度最終為零)。 我試着wait()
並滾動到元素,但我還沒有取得任何成功。
import * as Nightmare from 'nightmare'
import * as vo from 'vo'
import * as async from 'async'
import * as fs from 'fs'
const urls:String[] = [
'https://yahoo.com/'
]
Nightmare.action('snap', function(selector:String, done:Function) {
const self = this;
this.evaluate_now(function (selector) {
return Array.from(document.querySelectorAll(selector))
.map((ele:Element) => {
if (ele) {
const rect = ele.getBoundingClientRect()
const r:Function = Math.round
return {
x: r(rect.left),
y: r(rect.top),
width: r(rect.width),
height: r(rect.height)
}
}
})
}, function(err, clips) {
if (err) return done(err)
if (!clips) return done(new Error(`Selector not found`))
let snaps = []
const snap = (clip, cb) => {
self
.scrollTo(clip.y - clip.height, clip.x)
.screenshot(clip, cb)
.run()
}
async.mapSeries(clips.reverse(), snap, (err, res) => {
done(err, res)
})
}, selector)
})
const scrape = (url) => {
const nightmare = Nightmare({
show: true
});
nightmare
.goto(url)
.snap('.navbar')
.end()
.then((buffers:Buffer[]) => {
buffers.forEach((data, index) => {
fs.writeFileSync(`images/navbar-${index}.png`, data)
})
})
}
urls.forEach(scrape)
實際上,screenshot()函數從可見屏幕獲取坐標。
例如,如果任何元素的(x,y)是(10,1000)並且你的窗口大小是(800,600)那么你可以滾動(900:element.y,0)然后在(element.y-scroll)截取屏幕截圖。 y = 100,element.x)
我終於得到了代碼工作:
const Nightmare = require('nightmare');
const fs = require('fs');
const nightmare = Nightmare({
show: true,
openDevTools: true,
});
nightmare.goto('https://in.news.yahoo.com/')
.wait(1000)
.evaluate(getBounds, '.Cf')
.then(function(rects) {
console.log(rects);
function getScreenshot(rects, index) {
if (index == rects.length) return;
nightmare.scrollTo(rects[index].y, 0)
.screenshot(__dirname + '/images/navbar' + index + '.png', {
//60 is height of the top element which remains
x: rects[index].x-10,
y: 60,
width: rects[index].width+30,
height: rects[index].height +60
})
.then(function() {
console.log("Calling next. " + index);
getScreenshot(rects, index + 1);
}).catch(function(err) {
console.log(err);
})
};
getScreenshot(rects, 0);
})
.catch(function(err) {
console.log(err);
});
function getBounds(selector) {
var elements = document.querySelectorAll(selector);
if (elements && elements.length > 0) {
var arr = [];
const r = Math.round;
for (var ii = 0; ii < elements.length; ii++) {
var rect = elements[ii].getBoundingClientRect();
arr.push({
x: r(rect.left),
y: r(rect.top),
width: r(rect.width),
height: r(rect.height)
})
}
console.log("Elements found: ", arr.length);
return arr;
}
return null;
}
從不同的流程嘗試它,給出了更好的結果:方法的不同之處在於:首先滾動到元素然后取其邊界然后繼續截屏。
const Nightmare = require('nightmare');
const fs = require('fs');
const nightmare = Nightmare({
show: true,
openDevTools: false,
gotoTimeout: 45000
});
nightmare.goto('https://www.google.co.in/?#safe=off&q=nightmare')
.wait(1000)
.evaluate(getElements, 'div.g')
.then(() => {
console.log("Calling screenshots: ");
getAllScreenshots(0);
})
.catch(function(err) {
console.log(err);
});
function getAllScreenshots(index) {
console.log("Called with index: ", index)
nightmare.evaluate(function(index) {
const r = Math.round;
if(index >= window.__nightmare.output.length) {
return false;
}
var element = window.__nightmare.output[index];
console.log(index, element.innerHTML);
element.scrollIntoView(false);
var bound = element.getBoundingClientRect();
return {
x: r(bound.left)-10,
y: r(bound.top)-10,
width: r(element.clientWidth)+40,
height: r(element.clientHeight)+10
}
}, index)
.then(function(bound) {
if(!bound) {
return;
}
console.log("Taking screenshot: ", bound);
nightmare.wait(500).screenshot(__dirname + '/images/navbar' + index + '.png', bound)
.then(function() {
console.log("Calling Next of: ", index);
getAllScreenshots(index + 1);
}).catch(function(err) {
console.log(err);
})
})
.catch(function(err) {
console.log(err);
});
}
function getElements(selector) {
var elements = document.querySelectorAll(selector);
window.__nightmare.output = elements;
console.log(elements.length);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.