簡體   English   中英

Nightmare.js屏幕截圖緩沖區長度為0

[英]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.

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